我有一个String数组,我想通过LINQ添加到字符串生成器。
我基本上想说的是“对于此数组中的每个项目,在此StringBuilder中附加一行”。
我可以使用foreach循环很容易地做到这一点但是下面的代码似乎没有做任何事情。我错过了什么?
stringArray.Select(x => stringBuilder.AppendLine(x));
这在何处起作用:
foreach(String item in stringArray)
{
stringBuilder.AppendLine(item);
}
答案 0 :(得分:18)
如果您坚持以LINQy方式执行此操作:
StringBuilder builder = StringArray.Aggregate(
new StringBuilder(),
(sb, s) => sb.AppendLine(s)
);
或者,正如Luke在另一篇帖子的评论中指出的那样,你可以说
Array.ForEach(StringArray, s => stringBuilder.AppendLine(s));
Select
不起作用的原因是因为Select
用于投影和创建投影的IEnumerable
。所以代码行
StringArray.Select(s => stringBuilder.AppendLine(s))
不会在每次迭代时迭代StringArray
调用stringBuilder.AppendLine(s)
。相反,它会创建一个可以枚举的IEnumerable<StringBuilder>
。
我想你可以说
var e = stringArray.Select(x => stringBuilder.AppendLine(x));
StringBuilder sb = e.Last();
Console.WriteLine(sb.ToString());
但这确实很可怕。
答案 1 :(得分:4)
使用“ForEach”扩展方法代替“选择”。
stringArray.ForEach(x => stringBuilder.AppendLine(x));
答案 2 :(得分:0)
如果您使用的是.NET core,那么它将起作用:
stringBuilder.AppendJoin(Environment.NewLine, stringArray);
尽管它没有利用LINQ,但是可以在一行中完成它而无需添加任何额外的代码。
答案 3 :(得分:-1)
stringArray.DoForAll(x => StringBuilder.AppendLine(x));
其中,DoForAll
是一种扩展方法:
public static class CommonExtensions
{
public static void DoForAll<T>(this IEnumerable<T> items, Action<T> action) where T: class
{
if (action == null)
throw new ArgumentNullException("action");
foreach (var item in items)
action(item);
}
}