8

我有一个字符串数组,我想通过 LINQ 将它添加到字符串生成器中。

我基本上想说的是“对于这个数组中的每个项目,在这个 StringBuilder 中附加一行”。

我可以使用 foreach 循环很容易地做到这一点,但是下面的代码似乎没有做任何事情。我错过了什么?

stringArray.Select(x => stringBuilder.AppendLine(x));

这在哪里起作用:

foreach(String item in stringArray)
{
  stringBuilder.AppendLine(item);
}
4

4 回答 4

20

如果您坚持以 LINQy 方式进行操作:

StringBuilder builder = StringArray.Aggregate(
                            new StringBuilder(),
                            (sb, s) => sb.AppendLine(s)
                        );

或者,正如卢克在另一篇文章的评论中指出的那样,你可以说

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

但这真的很可怕。

于 2009-11-10T14:15:55.330 回答
4

使用“ForEach”扩展方法而不是“Select”。

stringArray.ToList().ForEach(x => stringBuilder.AppendLine(x));

或者

Array.ForEach(stringArray, x => stringBuilder.AppendLine(x));
于 2010-10-21T18:55:26.347 回答
0

如果您使用的是 .NET 核心,那么这将起作用:

stringBuilder.AppendJoin(Environment.NewLine, stringArray);

虽然它没有利用 LINQ,但它确实可以在一行中完成,而无需添加任何额外的代码。

于 2020-09-23T05:26:59.360 回答
-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);   
    }
} 
于 2009-11-10T14:12:48.650 回答