738


113

IList <文字列>またはIEnumerable <文字列>からのコンマ区切りリストの作成

IList`または IEnumerable`から文字列値のコンマ区切りのリストを作成するための最もきれいな方法は何ですか?

String.Join(…​)`は `string []`を操作するので、 `IList`や IEnumerable`のような型を簡単に文字列配列に変換できない場合には扱いが面倒です。

21 Answer


1,253


  • .NET 4 *

IList strings = new List{"1","2","testing"};
string joined = string.Join(",", strings);

*詳細

`+ IEnumerable +`は、LINQ(.NET 3.5)を使用して文字列配列に非常に簡単に変換できます。

IEnumerable strings = ...;
string[] array = strings.ToArray();

必要ならば、同等のヘルパーメソッドを書くのは簡単です。

public static T[] ToArray(IEnumerable source)
{
    return new List(source).ToArray();
}

それを次のように呼びます。

IEnumerable strings = ...;
string[] array = Helpers.ToArray(strings);

その後、 `+ string.Join +`を呼び出すことができます。 もちろん、あなたはヘルパーメソッドを使う必要はありません:

// C# 3 and .NET 3.5 way:
string joined = string.Join(",", strings.ToArray());
// C# 2 and .NET 2.0 way:
string joined = string.Join(",", new List(strings).ToArray());

後者はちょっと一口ですが:)

これが最も簡単な方法であり、パフォーマンスも非常に優れています - https://stackoverflow.com/questions/219519/whatsなど、パフォーマンスがどのようなものであるかについての質問が他にもあります。 c-method-arrayを単純な文字列に変換するための構文[this one]。

NET 4.0の時点で、http://msdn.microsoft.com/en-us/library/system.string.join [+ string.Join +]で利用可能なオーバーロードが増えているため、実際に書くことができます。
string joined = string.Join(",", strings);

もっとシンプル:)


172


参考までに、.NET 4.0バージョンの `+ string.Join()`にはhttp://msdn.microsoft.com/en-us/library/system.string.join.aspx[extra overloads]があります。任意のタイプの「 T 」を処理できる配列を含む、単なる配列ではなく、「 IEnumerable +」:

public static string Join(string separator, IEnumerable values)
public static string Join(string separator, IEnumerable values)


59


これを確認する最も簡単な方法は、LINQの `+ Aggregate`メソッドを使用することです。

string commaSeparatedList = input.Aggregate((a, x) => a + ", " + x)


29


文字列値のカンマ区切りのリストを作成する最も簡単な方法は、単純に次のようになります。

string.Join( "、"、stringEnumerable);

これは完全な例です。

IEnumerable stringEnumerable = new List(); stringList.Add( "Comma"); stringList.Add( "Separated");

string.Join( "、"、stringEnumerable);

ヘルパー関数を作成する必要はありません。これは.NET 4.0以降に組み込まれています。


9


オブジェクトのリストの特定のプロパティ(およびそのToString()ではなく)に参加するために検索しているときに、ここに到達したので、ここに承認された答えを追加します。

var commaDelimited = string.Join( "、"、students.Where(i => i.Category == studentCategory).Select(i => i.FirstName));


8


これは別の拡張方法です:

public static string Join(このIEnumerableソース、文字列のセパレータ){return string.Join(separator、source); }


7


パフォーマンスを比較すると、勝者は「ループして結合して後退します」です。 実際には "次の列挙型の手動移動"も同じです(stddevを参照)。

BenchmarkDotNet = v0.10.5、OS = Windows 10.0.14393プロセッサ= Intel Core i5-2500K CPU 3.30GHz(Sandy Bridge)、ProcessorCount = 4周波数= 3233539Hz、解像度= 309.2587ns、タイマー= TSC [ホスト]:Clr 4.0。 30319.42000、64ビットRyuJIT-v4.6.1637.0 Clr:Clr 4.0.30319.42000、64ビットRyuJIT-v4.6.1637.0コア:.NETコア4.6.25009.03、64ビットRyuJIT

方法|仕事|ランタイム意味エラー| StdDevミン|マックス中央値|ランク| Gen 0 |割り当て済み---------------------- | ----- | -------- | ---------:|  - ---------:| ----------:| ---------:| ---------:| ----- ----:| -----:| -------:| ----------:| StringJoin | Clr | Clr | 28.24 0.4381 us | 0.3659 27.68 us | 29.10 28.21 8 | 4.9969 | 16.3 kB |セパレータの代用Clr | Clr | 17.90 0.2900 us | 0.2712 us | 17.55 us | 18.37 us | 17.80 us | 6 | 4.9296 | 16.27 kB | SeparatorStepBack | Clr | Clr | 16.81 us | 0.1289 0.1206 us | 16.64 17.05 us | 16.81 us | 2 | 4.9459 | 16.27 kB |列挙可能Clr | Clr | 17.27 0.0736 0.0615 us | 17.17 us | 17.36 17.29 4 | 4.9377 | 16.27 kB | StringJoin |コア|コア| 27.51 0.5340 0.4995 us | 26.80 us | 28.25 us | 27.51 7 | 5.0296 | 16.26 kB |セパレータの代用コア|コア| 17.37 0.1664 us | 0.1557 us | 17.15 us | 17.68 us | 17.39 5 | 4.9622 | 16.22 kB | SeparatorStepBack |コア|コア| 15.65 us | 0.1545 us | 0.1290 us | 15.45 us | 15.82お問い合わせ15.66 us | 1 | 4.9622 | 16.22 kB |列挙可能コア|コア| 17.00 us | 0.0905 us | 0.0654 us | 16.93 17.12 16.98 us | 3 | 4.9622 | 16.22 kB |

コード:

パブリッククラスBenchmarkStringUnion {List testData = new List();} public BenchmarkStringUnion(){(int i = 0; i <1000; i){testData.Add(i.ToString()); [ベンチマーク]パブリック文字列StringJoin(){var text = string.Join( "、"、testData);テキストを返します。 [ベンチマーク]パブリック文字列SeparatorSubstitution(){var sb = new StringBuilder();} var separator = String.Empty; foreach(testData内のvar値){sb.Append(区切り文字).Append(値); separator = "、"; sb.ToString()を返します。 }

[ベンチマーク]公開文字列SeparatorStepBack(){var sb = new StringBuilder();} foreach(testData内のvar item)sb.Append(item).Append( '、'); if(sb.Length> = 1)sb.Length--; sb.ToString()を返します。 }

[ベンチマーク]パブリック文字列Enumerable(){var sb = new StringBuilder();} var e = testData.GetEnumerator(); bool moveNext = e.MoveNext(); while(moveNext){sb.Append(e.Current); moveNext = e.MoveNext(); if(moveNext)sb.Append( "、"); sb.ToString()を返します。 }}


7


exで囲む必要がある場合の具体的な必要性

string [] arr = {"jj"、 "laa"、 "123"};リストmyList = arr.ToList();

// 'jj'、 'laa'、 '123' Console.WriteLine(string.Join( "、"、myList.ConvertAll(m => string.Format( "'{0}'"、m)))ToArray( ));


7


この議論に少し遅れて到着しましたが、これは私の貢献です。 CSV文字列に変換される `+ IList OrderIds +`がありますが、以下は一般的なものであり、他のタイプでは変更されません。

string csv = OrderIds.Aggregate(new StringBuilder(),
             (sb, v) => sb.Append(v).Append(","),
             sb => {if (0 < sb.Length) sb.Length--; return sb.ToString();});

短くて甘い、StringBuilderを使用して新しい文字列を作成し、StringBuilderの長さを1つ縮小して最後のカンマを削除し、CSV文字列を返します。

複数の `+ Append()`を使用して文字列+コンマを追加するように更新しました。 Jamesのフィードバックから、Reflectorを使用して ` StringBuilder.AppendFormat()`を確認しました。 ` AppendFormat()`はStringBuilderを使用してフォーマット文字列を構築するため、このコンテキストでは複数の ` Appends()+`を使用するよりも効率が悪くなります。


6


ちょっとぎこちない何かが、それは動作します:

string divisionsCSV = String.Join( "、"、((List)divisions)).ConvertAll(d => d.DivisionID.ToString( "b"))。ToArray());

コンバーターを渡した後、リストからCSVを取得します(この場合はd ⇒ d.DivisionID.ToString( "b"))。

ハッキーだがうまくいく - おそらく拡張メソッドにすることができるだろうか?