生成逗号分隔值

假设我有一个字符串集合:

"foo" "bar" "xyz" 

我想从列表中生成逗号分隔值,如下所示:

 "foo, bar, xyz" 

注意最后缺少“,”。

我知道有很多方法可以生成这个:

  • 使用for-loop和string.Format()或StringBuilder。
  • 如果值> 0,则使用整数计数器并删除结尾“,”
  • 第一次运行时不要放“,”
  • 等等

我现在拥有的示例代码:

 if (strs.Count() > 0) { var sb = new StringBuilder(); foreach (var str in strs) sb.AppendFormat("{0}, ", str); return sb.Remove(0, 2).ToString(); } 

对于上述场景,高度可重用的最佳代码是什么?为什么?

String.Join是正确的答案,但在IEnumerable的情况下,Linq通常比for循环短:

 someStringCollection.Aggregate((first, second) => first + ", " + second); 

您希望使用string.Join方法,该方法存在于BCL中以实现此目的。

例:

 var myArray = new string[] { "one", "two", "three" }; var output = string.Join(", ", myArray); 

或者,如果您使用的是.NET 3.5,则可以使用任何IEnumerable执行此操作:

 var output = string.Join(", ", myEnumerable.ToArray()); 

(请注意,这并不能提供所需的最佳性能,尽管它显然仍然是’O(n)’,并且应该适用于几乎所有情况)。

现在,如果你的枚举不是string类型(通常是IEnumerable ),你可以使用Select方法将结果转换为字符串,例如

 var output = string.Join(", ", myEnumerable.Select(e => e.ToString()).ToArray()); 

我不确定你是否正在处理可能包含逗号的值,但这可以通过将它们括在引号( " )中并转义引号来解决,类似于CSV格式。

 var output = string.Join(", ", items.Select(x => x.Contains(",") ? "\"" + x.Replace("\"", "\"\"") + "\"" : x); 

当然,将它们重新拆分是一个稍微重要的任务,这需要一些正则表达式。

正如其他人所说: String.Join 通常是最好的方法。 但是,如果你只有一个IEnumerable而不是一个数组呢? 当您使用延迟执行从文件中读取它们时,可能有代码来枚举这些代码。 在这种情况下,String.Join不是很好,因为你必须遍历字符串两次 – 一次创建数组,一次加入它。 在这种情况下,你想要更像这样的东西:

 public static string ToDelimitedString(this IEnumerable source, string delimiter) { string d = ""; var result = new StringBuilder(); foreach( string s in source) { result.Append(d).Append(s); d = delimiter; } return result.ToString(); } 

这将执行几乎与String.Join一样好,并在更一般的情况下工作。 然后,给定一个字符串数组或任何其他IEnumerable,你可以像这样调用它:

 string finalStr = MyStrings.ToDelimitedString(","); 
 string finalstr = String.Join(",", strs); 

使用

 string s = string.Join (",", new string[] {"aaa", "bbb", "ccc"}); 

使用String.Join

如果你有一个字符串数组,请使用Noldorin的解决方案。

但如果它是其他一些集合类型,我可能会这样做:

 if (strs.Count() > 0) { var sb = new StringBuilder(); foreach (var str in strs) sb.AppendFormat("{0} {1}", (0 == sb.Length ? "" : ","), str); return sb.ToString(); }