1

HashSet<String>をとってエレガントに文字列に変換したいと思います。私はそのように繰り返すことができます:

HashSet<String> words = new HashSet<string>() { "alpha", "beta", "delta" };

string joined = "";
foreach (var w in words) 
  joined += w + ",";

if(joined.Length > 0)
  joined = joined.SubString(0,joined.Length-1); // remove final comma

LinQこれをエレガントかつ効率的に行う方法はありますか?

私がこれを行うことを考えることができる唯一の方法は、最初にそれを配列に変換することです:

HashSet<String> words = new HashSet<string>() { "alpha", "beta", "delta" };
string joined = String.Join(",",words.ToArray());

しかし、それから私は二重変換を行っています。効率的で明確な便利でダンディなLinQ式はありますか?

回答1(マーのアイデアから)

public static string JoinItems(this IEnumerable<string> items, string joiner) {
    StringBuilder sb = new StringBuilder("");

    foreach (var i in items) 
        sb.AppendFormat("{0}{1}",i,joiner);

    if(sb.Length>0) 
        return sb.Remove(sb.Length - joiner.Length, joiner.Length).ToString();
    else
       return sb.ToString();
}

列挙子を使用した回答2(Martinのソリューションから)

public static string JoinItems<T>(this IEnumerable<T> items, string delim) {
    var sb = new StringBuilder();
    var i = items.GetEnumerator();
    if (i.MoveNext()) {
        sb.Append(i.Current);
        while (i.MoveNext()) {
            sb.Append(delim);
            sb.Append(i.Current);
        }
    }
    return sb.ToString();
}
4

3 に答える 3

3

私はあなたのメソッドを取り、最後のコンマを削除する必要がないように変更しました。また、毎回フォーマットを解析するすべての作業を回避するという理由AppendFormatだけで、をに変更しました。Append

public static string JoinItems(this IEnumerable<string> items, string joiner)
{
    StringBuilder sb = new StringBuilder(); 
    string delim = "";

    foreach (var i in items)
    {
        sb.Append(delim);
        sb.Append(i);
        delim = joiner;
    }

    return sb.ToString(); 
} 
于 2010-09-16T23:25:22.527 に答える
1

String.Join()行に二重変換が表示されません。ひどいものではない1つの変換ToArray()が表示され、それからString.Join()を実行します。これはうまく機能します。

.Net 4には、変換なしで機能するIEnumerableを受け取るString.Join()があります。古いフレームワークバージョンを使用している場合は、「this」パラメーターとしてセパレーターを取り、IEnumerableを結合する文字列の独自の拡張メソッドを作成できます。必ずstringbuilderを使用してパフォーマンスを確認してください。

于 2010-09-16T19:36:37.483 に答える
1

これにより、追加のコピーや各反復のチェックなしでトリックが実行されます。

String JoinItems<T>(IEnumerable<T> items) {
  var stringBuilder = new StringBuilder();
  var i = items.GetEnumerator();
  if (i.MoveNext()) {
    stringBuilder.Append(i.Current);
    while (i.MoveNext()) {
      stringBuilder.Append(", ");
      stringBuilder.Append(i.Current);
    }
  }
  return stringBuilder.ToString();
}
于 2010-09-16T22:55:59.617 に答える