使用LinQ </string>序列化HashSet <string>

时间:2010-09-16 19:28:56

标签: linq string join hashset

我想采用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());

但是,我正在进行双重转换。是否会有一些方便的-Dandy LinQ表达式有效且清晰?

答案1(来自marr的想法)

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();
}

ANSWER 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();
}

3 个答案:

答案 0 :(得分: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(); 
} 

答案 1 :(得分:1)

我没有在String.Join()行中看到双重转换。我看到一个转换ToArray(),这并不可怕,然后它执行String.Join(),表现良好。

.Net 4中有一个String.Join(),它带有一个IEnumerable,可以在没有转换的情况下工作。如果您使用的是较旧的框架版本,则可以为字符串编写自己的扩展方法,该方法将分隔符作为“this”参数,然后加入IEnumerable。请确保使用stringbuilder来提高性能。

答案 2 :(得分: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();
}