问题
I've got a String array that I'm wanting to add to a string builder by way of LINQ.
What I'm basically trying to say is "For each item in this array, append a line to this StringBuilder".
I can do this quite easily using a foreach loop however the following code doesn't seem to do anything. What am I missing?
stringArray.Select(x => stringBuilder.AppendLine(x));
Where as this works:
foreach(String item in stringArray)
{
stringBuilder.AppendLine(item);
}
回答1:
If you insist on doing it in a LINQy way:
StringBuilder builder = StringArray.Aggregate(
new StringBuilder(),
(sb, s) => sb.AppendLine(s)
);
Alternatively, as Luke pointed out in a comment on another post, you could say
Array.ForEach(StringArray, s => stringBuilder.AppendLine(s));
The reason that Select
does not work is because Select
is for projecting and creating an IEnumerable
of the projection. So the line of code
StringArray.Select(s => stringBuilder.AppendLine(s))
does not iterate over the StringArray
calling stringBuilder.AppendLine(s)
on each iteration. Rather, it creates an IEnumerable<StringBuilder>
that can be enumerated over.
I suppose that you could say
var e = stringArray.Select(x => stringBuilder.AppendLine(x));
StringBuilder sb = e.Last();
Console.WriteLine(sb.ToString());
but that is really hideous.
回答2:
Use the "ForEach" extension method instead of "Select".
stringArray.ForEach(x => stringBuilder.AppendLine(x));
回答3:
stringArray.DoForAll(x => StringBuilder.AppendLine(x));
Where, DoForAll
is an extension method:
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);
}
}
来源:https://stackoverflow.com/questions/1708247/linq-to-append-to-a-stringbuilder-from-a-string