Was ist der effizienteste Weg, um die alte Schule zu schreiben:
StringBuilder sb = new StringBuilder();
if (strings.Count > 0)
{
foreach (string s in strings)
{
sb.Append(s + ", ");
}
sb.Remove(sb.Length - 2, 2);
}
return sb.ToString();
... in LINQ?
c#
linq
string-concatenation
tags2k
quelle
quelle
Antworten:
Diese Antwort zeigt die Verwendung von LINQ (
Aggregate
) wie in der Frage angefordert und ist nicht für den täglichen Gebrauch vorgesehen. Da dies kein verwendetStringBuilder
, wird es für sehr lange Sequenzen eine schreckliche Leistung haben. Für den regulären Code verwenden SieString.Join
wie in der anderen Antwort gezeigtVerwenden Sie aggregierte Abfragen wie folgt:
Dies gibt aus:
Ein Aggregat ist eine Funktion, die eine Sammlung von Werten verwendet und einen Skalarwert zurückgibt. Beispiele aus T-SQL sind min, max und sum. Sowohl VB als auch C # unterstützen Aggregate. Sowohl VB als auch C # unterstützen Aggregate als Erweiterungsmethoden. Mit der Punktnotation ruft man einfach eine Methode auf einem IEnumerable auf Objekt auf.
Denken Sie daran, dass aggregierte Abfragen sofort ausgeführt werden.
Weitere Informationen - MSDN: Aggregierte Abfragen
Wenn Sie wirklich
Aggregate
eine Variante verwenden möchten, verwenden SieStringBuilder
die im CodeMonkeyKing- Vorschlag vorgeschlagene Variante, die ungefähr dem gleichen Code wie normal entspricht,String.Join
einschließlich einer guten Leistung für eine große Anzahl von Objekten:quelle
""
der erste Wert, der in verwendetcurrent
wird, eine leere Zeichenfolge , da Sie mit gesetzt haben . Für 1 oder mehr Elemente stehen Sie also immer,
am Anfang der Zeichenfolge.In .Net 4, gibt es eine neue Überlast für
string.Join
das akzeptiertIEnumerable<string>
. Der Code würde dann so aussehen:quelle
Warum Linq verwenden?
Das funktioniert perfekt und akzeptiert,
IEnumerable<string>
soweit ich mich erinnere. Hier brauchen SieAggregate
nichts, was viel langsamer ist.quelle
String.Join(",", s.ToArray())
in den älteren Versionen.Haben Sie sich die Aggregate-Erweiterungsmethode angesehen?
quelle
Echtes Beispiel aus meinem Code:
Eine Abfrage ist ein Objekt mit einer Name-Eigenschaft, bei der es sich um eine Zeichenfolge handelt. Ich möchte, dass die Namen aller Abfragen in der ausgewählten Liste durch Kommas getrennt werden.
quelle
Hier ist der kombinierte Join / Linq-Ansatz, für den ich mich entschieden habe, nachdem ich mir die anderen Antworten und die in einer ähnlichen Frage behandelten Probleme angesehen habe (nämlich, dass Aggregate und Concatenate mit 0 Elementen fehlschlagen).
string Result = String.Join(",", split.Select(s => s.Name));
oder (wenn
s
es sich nicht um eine Zeichenfolge handelt)string Result = String.Join(",", split.Select(s => s.ToString()));
StringBuilder
) zur ImplementierungUnd natürlich kümmert sich Join um das lästige letzte Komma, das sich manchmal in andere Ansätze einschleicht (
for
,foreach
), weshalb ich überhaupt nach einer Linq-Lösung gesucht habe.quelle
.Select()
gefällt mir, weil die Verwendung dieser Option einen einfachen Ort bietet, um jedes Element während dieses Vorgangs zu ändern. Zum Beispiel, wickeln Sie jeden Gegenstand in einen Charakter wie diesenstring Result = String.Join(",", split.Select(s => "'" + s + "'"));
Sie können verwenden
StringBuilder
inAggregate
:(Das
Select
ist nur da, um zu zeigen, dass Sie mehr LINQ-Sachen machen können.)quelle
new[] {"one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) =>{if (sb.Length > 0) sb.Append(", ");sb.Append(s);return sb;}).ToString();
if (length > 0)
indem Sie die Linq nicht überprüfen und herausnehmen.new[] {"", "one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) => (String.IsNullOrEmpty(sb.ToString())) ? sb.Append(s) : sb.Append(", ").Append(s)).ToString();
Schnelle Leistungsdaten für den Fall StringBuilder vs Select & Aggregate über 3000 Elemente:
Komponententest - Dauer (Sekunden) LINQ_StringBuilder - 0,0036644
LINQ_Select.Aggregate - 1,8012535
quelle
Ich benutze immer die Erweiterungsmethode:
quelle
string.Join
in .net 4 kann man schon eineIEnumerable<T>
beliebige nehmenT
.Mit " supercooler LINQ-Methode " könnten Sie darüber sprechen, wie LINQ die funktionale Programmierung durch die Verwendung von Erweiterungsmethoden viel angenehmer macht. Ich meine, der syntaktische Zucker, mit dem Funktionen visuell linear (nacheinander) verkettet werden können, anstatt (ineinander) zu verschachteln. Zum Beispiel:
kann so geschrieben werden:
Sie können sehen, wie das zweite Beispiel leichter zu lesen ist. Sie können auch sehen, wie mehr Funktionen mit weniger Einrückungsproblemen oder dem Lispy hinzugefügt werden können Abschlussparens am Ende des Ausdrucks erscheinen.
Viele der anderen Antworten besagen, dass dies der
String.Join
richtige Weg ist, da es am schnellsten oder am einfachsten zu lesen ist. Wenn Sie jedoch meine Interpretation von " supercooler LINQ-Methode " verwenden, lautet die Antwort, sie zu verwendenString.Join
, sie jedoch in eine Erweiterungsmethode im LINQ-Stil einzuschließen, mit der Sie Ihre Funktionen auf visuell ansprechende Weise verketten können. Wenn Sie also schreiben möchten, müssensa.Concatenate(", ")
Sie nur Folgendes erstellen:Dies liefert Code, der genauso performant ist wie der direkte Aufruf (zumindest in Bezug auf die Komplexität des Algorithmus) und in einigen Fällen den Code (je nach Kontext) besser lesbar macht, insbesondere wenn anderer Code im Block den verketteten Funktionsstil verwendet .
quelle
Bei dieser vorherigen Frage gibt es verschiedene alternative Antworten - die zwar auf ein ganzzahliges Array als Quelle abzielten, aber allgemeine Antworten erhielten.
quelle
Hier wird reines LINQ als einzelner Ausdruck verwendet:
Und es ist verdammt schnell!
quelle
Ich werde ein wenig schummeln und eine neue Antwort darauf herauswerfen, die das Beste von allem hier zusammenzufassen scheint, anstatt es in einen Kommentar zu stecken.
Sie können dies also in einer Zeile festhalten:
Bearbeiten: Sie möchten entweder zuerst nach einer leeren Aufzählung suchen oder eine hinzufügen
.Replace("\a",string.Empty);
am Ende des Ausdrucks . Ich schätze, ich habe versucht, ein bisschen zu schlau zu werden.Die Antwort von @ a.friend ist möglicherweise etwas performanter. Ich bin mir nicht sicher, was Replace unter der Haube im Vergleich zu Remove tut. Die einzige andere Einschränkung, wenn Sie aus irgendeinem Grund Zeichenfolgen zusammenfassen wollten, die mit \ a endeten, würden Sie Ihre Trennzeichen verlieren ... Ich finde das unwahrscheinlich. In diesem Fall haben Sie andere ausgefallene Charaktere zur Auswahl.
quelle
Sie können LINQ
string.join()
sehr effektiv kombinieren . Hier entferne ich ein Element aus einer Zeichenfolge. Es gibt auch bessere Möglichkeiten, dies zu tun, aber hier ist es:quelle
Viele Möglichkeiten hier. Sie können LINQ und einen StringBuilder verwenden, damit Sie die Leistung auch so erhalten:
quelle
builder.Length > 0
im ForEach nicht zu überprüfen und das erste Komma nach dem ForEach zu entfernenIch habe Folgendes schnell und schmutzig gemacht, als ich eine IIS-Protokolldatei mit linq analysiert habe. Es hat bei 1 Million Zeilen ziemlich gut funktioniert (15 Sekunden), obwohl beim Versuch, 2 Millionen Zeilen zu speichern, ein Speicherfehler aufgetreten ist.
Der wahre Grund, warum ich linq verwendet habe, war für ein Distinct (), das ich zuvor brauchte:
quelle
Ich habe vor einiger Zeit darüber gebloggt, was ich getan habe, um genau das zu sein, wonach Sie suchen:
http://ondevelopment.blogspot.com/2009/02/string-concatenation-made-easy.html
In diesem Blogbeitrag wird beschrieben, wie Sie Erweiterungsmethoden implementieren, die unter IEnumerable funktionieren und den Namen "Verketten" tragen. Auf diese Weise können Sie Folgendes schreiben:
Oder ausgefeiltere Dinge wie:
quelle