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