Frage an lambda, stringbuilder, c#, linq – LINQ zum Anhängen eines StringBuilder aus einem String []

6

Ich habe ein String-Array, das ich über LINQ zu einem String-Builder hinzufügen möchte.

Ich versuche im Grunde zu sagen: "Hängen Sie für jedes Element in diesem Array eine Zeile an diesen StringBuilder an."

Ich kann dies ziemlich einfach mit einer foreach-Schleife tun, aber der folgende Code scheint nichts zu tun. Was vermisse ich?

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

Wo wie das funktioniert:

foreach(String item in stringArray)
{
  stringBuilder.AppendLine(item);
}
Ich habe StringBuilder und StringArray umbenannt, um ein erstes Zeichen in Kleinbuchstaben zu verwenden. Nur um klarzustellen, dass ich mich auf Instanzvariablen und nicht auf Typen beziehe. Jamie Dixon
Ich würde den Befehl .Select nicht verwenden. Ist der Befehl ForEach nicht verfügbar? sebagomez
Ja, so ist es...msdn.microsoft.com/en-us/library/zecdkyw2.aspx :) sebagomez

Deine Antwort

3   die antwort
4

Verwenden Sie die Erweiterungsmethode "ForEach" anstelle von "Select".

stringArray.ForEach(x => stringBuilder.AppendLine(x));
-1
stringArray.DoForAll(x => StringBuilder.AppendLine(x));

Woher,DoForAll ist eine Erweiterungsmethode:

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);   
    }
} 
Was istDoForAll? jason
@vladhorby: Ein Blick auf das WarumDoForAll und andere gleichwertige Erweiterungen sind nicht implementiert:blogs.msdn.com/ericlippert/archive/2009/05/18/… jason
Entschuldigung, ich hatte diese Erweiterungsmethode so lange, dass ich vergessen habe, dass sie nicht Teil des Frameworks ist. öffentliche statische Klasse CommonExtensions {public static void DoForAll <T> (diese IEnumerable <T> -Elemente, Aktion <T> -Aktion) wobei T: class {if (action == null) neue ArgumentNullException ("action") auslösen; foreach (var item in items) action (item); }} vladhorby
18

Wenn Sie darauf bestehen, dies auf LINQy-Weise zu tun:

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

Alternativ auch alsLuke In einem Kommentar auf einen anderen Beitrag hingewiesen, könnte man sagen

Array.ForEach(StringArray, s => stringBuilder.AppendLine(s));

Der Grund dassSelect geht nicht liegt daranSelect dient zum projizieren und erstellen einesIEnumerable der Projektion. Also die Codezeile

StringArray.Select(s => stringBuilder.AppendLine(s))

iteriert nicht über dieStringArray BerufungstringBuilder.AppendLine(s) bei jeder Iteration. Vielmehr schafft es eineIEnumerable<StringBuilder> das kann über aufgezählt werden.

Das könnte man wohl sagen

var e = stringArray.Select(x => stringBuilder.AppendLine(x));
StringBuilder sb = e.Last();
Console.WriteLine(sb.ToString());

aber das ist wirklich abscheulich.

Ist garantiert, dass Last () iteriert? Anstatt nur stringArray [stringArray.count-1] abzurufen? Ich glaube, ich hätte ToList () vorgezogen. Taemyr
Vielen Dank, Jason. Ihre Antwort erklärt, warum die Select-Methode nicht das gewünschte Ergebnis erzielt hat und warum foreach funktioniert hat. Ich bleibe beim foreach. Ich war wirklich nur neugierig, was mir gefehlt hat. Jetzt weiß ich. Jamie Dixon

Verwandte Fragen