94


22

.NETでint []を文字区切りの文字列に結合する方法

整数の配列があります。

int[] number = new int[] { 2,3,6,7 };

これらを数字で区切られた1つの文字列に変換する最も簡単な方法は何ですか?( "" 2,3,6,7 "`のように)

私はC#と.NET 3.5にいます。

10 Answer


154


var ints = new int [] {1、2、3、4、5}; var result = string.Join( "、"、ints.Select(x => x.ToString())。ToArray()); Console.WriteLine(結果); // "1,2,3,4,5"を印刷する

編集

私はいくつかの解決策がStringBuilderの使用法を宣伝するのを見ます。 JoinメソッドがIEnumerable引数を取るべきであるという苦情があります。

私はあなたを失望させるつもりです:) String.Joinは単一の理由で配列を必要とします - パフォーマンス。 結合方法では、必要な量のメモリを効果的に事前割り当てするためにデータのサイズを知る必要があります。

これは、String.Joinメソッドの内部実装の一部です。

// length computed from length of items in input array and length of separator
文字列str = FastAllocateString(長さ);固定(char * chRef =

提案されたメソッドのパフォーマンスを比較するのが面倒すぎます。 しかし、何かがJoinが勝つことを私に言う:)


32


OPは.NET 3.5を指定していますが、C#2を適用した.NET 2.0でこれを行いたい人はこれを行うことができます。

string.Join( "、"、Array.ConvertAll(ints、Convert.ToString));

C#3ではラムダが型推論に役立つかもしれませんが、Convert.xxx関数の使用がラムダの代わりになるより良いケースが他にもたくさんあります。

NET 2.0で動作するかなりコンパクトなC#3バージョンはこれです:
string.Join( "、"、Array.ConvertAll(int、item => item.ToString()))


10


2つのアプローチの1つの混合は、StringBuilderを使用したIEnumerableに拡張メソッドを書くことです。 これは、変換を指定するのか、それとも単純なToStringに頼るのかによってオーバーロードが異なる例です。 他の種類のJoinとの混同を避けるために、 "Join"ではなく "JoinStrings"というメソッドを使用しました。 おそらく誰かがより良い名前を思い付くことができます:)

システムを使用する。 System.Collections.Genericを使用します。 System.Textを使用します。

public static class Extensions {public static string JoinStrings(このIEnumerableソース、Funcプロジェクション、文字列セパレータ){StringBuilder builder = new StringBuilder();最初のブール= true。 foreach(ソース中のT要素){if(first){first = false;} } else {builder.Append(separator);} builder.Append(projection(element));戻り値builder.ToString(); }

public static string JoinStrings(このIEnumerableソース、文字列のセパレータ){JoinStrings(source、t => t.ToString()、separator); }}

クラスTest {

public static void Main(){int [] x = {1、2、3、4、5、10、11};

Console.WriteLine(x.JoinStrings( ";")); Console.WriteLine(x.JoinStrings(i => i.ToString( "X")、 "、")); }}


8


String.Join(";", number.Select(item => item.ToString()).ToArray());

結合する前に各項目を String`に変換する必要があるので、 Select`とラムダ式を使うのは理にかなっています。 これは他の言語では `map`と同等です。 それから `String.Join`は文字列配列しか受け付けないので、結果として得られる文字列のコレクションを配列に戻す必要があります。

ToArray()はちょっと醜いと思います。 String.Join`は本当に IEnumerable`を受け入れるべきです、それを配列だけに制限する理由はありません。 これはおそらく、 `Join`がジェネリックスより前のもので、配列が唯一の型付きコレクションとして利用可能だったからです。


5


整数の配列が大きい場合は、StringBuilderを使用するとパフォーマンスが向上します。 例えば。:

StringBuilder builder = new StringBuilder();文字区切り文字= '、'; foreach(integerArrayのint値){if(builder.Length> 0)builder.Append(separator); builder.Append(value); string result = builder.ToString();

編集:私がこれを投稿したとき、私は "StringBuilder.Append(int value)"が文字列オブジェクトを作成せずに整数値の文字列表現を追加することを内部的に管理したという誤った印象を受けました。 これは間違っています。Reflectorでメソッドを調べると、単にvalue.ToString()が追加されているだけです。

したがって、唯一の潜在的なパフォーマンスの違いは、この手法は1つの配列の作成を避け、ガベージコレクションのために文字列を少し早く解放することです。 実際には、これは測定可能な違いを生じないので、私は このより良い解決策


5


問題は、「これらを数字で区切られた単一の文字列に変換する最も簡単な方法」です。

最も簡単な方法は次のとおりです。

int [] numbers = new int [] {2,3,6,7}; string number_string = string.Join( "、"、numbers);
// do whatever you want with your exciting new number string

編集:これは.NET 4.0でのみ動作します、私が質問を最初に読んだとき、私は.NET 3.5の要件を逃しました。


2


読みやすさと保守性の点でラムダ式に同意しますが、必ずしも最良の選択肢とは限りません。 IEnumerable / ToArrayとStringBuilderの両方のアプローチを使用することのマイナス面は、項目または文字のどちらかで動的にリストを大きくする必要があることです。

速度が簡潔さよりも重要であるというまれなケースでは、以下のほうがより効率的です。

int [] number = new int [] {1、2、3、4、5}; string [] strings =新しい文字列[number.Length]; for(int i = 0; i <number.Length; i)strings [i] = number [i] .ToString(); string result = string.Join( "、"、strings);


2


ints.Aggregate( ""、(str、n)=> str "、" n).Substring(1);

もっと簡単な方法もあると思いました。 パフォーマンスについて知らない、誰かが(理論的な)アイデアを持っていますか?


2


NET 4.0では、文字列結合は `params object []`のオーバーロードを持っているので、次のように単純です。
int[] ids = new int[] { 1, 2, 3 };
string.Join(",", ids);

int[] ids = new int[] { 1, 2, 3 };
System.Data.Common.DbCommand cmd = new System.Data.SqlClient.SqlCommand("SELECT * FROM some_table WHERE id_column IN (@bla)");
cmd.CommandText = cmd.CommandText.Replace("@bla",  string.Join(",", ids));
NET 2.0では、そのような過負荷がないので、少し難しいです。 それであなたはあなた自身の一般的な方法を必要とします:
public static string JoinArray(string separator, T[] inputTypeArray)
{
    string strRetValue = null;
    System.Collections.Generic.List ls = new System.Collections.Generic.List();

    for (int i = 0; i < inputTypeArray.Length; ++i)
    {
        string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture);

        if (!string.IsNullOrEmpty(str))
        {
            // SQL-Escape
            // if (typeof(T) == typeof(string))
            //    str = str.Replace("'", "''");

            ls.Add(str);
        } // End if (!string.IsNullOrEmpty(str))

    } // Next i

    strRetValue= string.Join(separator, ls.ToArray());
    ls.Clear();
    ls = null;

    return strRetValue;
}
NET 3.5では、拡張メソッドを使用できます。
public static class ArrayEx
{

    public static string JoinArray(this T[] inputTypeArray, string separator)
    {
        string strRetValue = null;
        System.Collections.Generic.List ls = new System.Collections.Generic.List();

        for (int i = 0; i < inputTypeArray.Length; ++i)
        {
            string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture);

            if (!string.IsNullOrEmpty(str))
            {
                // SQL-Escape
                // if (typeof(T) == typeof(string))
                //    str = str.Replace("'", "''");

                ls.Add(str);
            } // End if (!string.IsNullOrEmpty(str))

        } // Next i

        strRetValue= string.Join(separator, ls.ToArray());
        ls.Clear();
        ls = null;

        return strRetValue;
    }

}

そのため、JoinArray拡張メソッドを使用できます。

int[] ids = new int[] { 1, 2, 3 };
string strIdList = ids.JoinArray(",");

ExtensionAttributeをコードに追加すれば、.NET 2.0でその拡張メソッドを使用することもできます。

// you need this once (only), and it must be in this namespace
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute {}
}


1


できるよ

ints.ToString( "、")ints.ToString( "|")ints.ToString( ":")

チェックアウト

http://www.codemeit.com/linq/c-array-delimited-tostring.html[配列、リスト、辞書、総称IEnumerableの区切り文字のToString]