Wie verkette ich zwei IEnumerable <T> zu einem neuen IEnumerable <T>?


201

Ich habe zwei Instanzen von IEnumerable<T>(mit dem gleichen T). Ich möchte eine neue Instanz, von IEnumerable<T>der beide verkettet sind.

Gibt es eine integrierte Methode in .Net, um dies zu tun, oder muss ich sie selbst schreiben?


9
Möglicherweise möchten Sie code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b mit einem Lesezeichen versehen .
C-Pfund Guru

Antworten:


332

Ja, LINQ to Objects unterstützt dies mit Enumerable.Concat:

var together = first.Concat(second);

NB: Sollte firstoder secondsollte null sein, würden Sie eine erhalten ArgumentNullException. Um dies zu vermeiden und Nullen wie eine leere Menge zu behandeln, verwenden Sie den Null-Koaleszenzoperator wie folgt:

var together = (first ?? Enumerable.Empty<string>()).Concat(second ?? Enumerable.Empty<string>()); //amending `<string>` to the appropriate type

1
Ich vergesse immer, nach Erweiterungsmethoden zu suchen, tx.
Samuel Rossille

10
@SamuelRossille Vergessen Sie auch nicht, dass die Namen der Aktionen, die Sie ausführen möchten, wahrscheinlich nahe beieinander liegen, wenn Sie nicht genau das nennen, wonach Sie suchen. Stöbern Sie immer in IntelliSense, Sie lernen viel.
Adam Houldsworth

3
Ist es schlecht, second = first.Concat (second) zu machen? Werden wir Probleme mit der Parallelität haben?
user2934433

4
@ user2934433: Nein, das ist absolut in Ordnung.
Jon Skeet

2
Nur eine schnelle Anmerkung. Es ist erforderlich, den using System.Linq Namespace oben in der Codedatei zu importieren , um die gewünschte Erweiterungsmethode in der IDE Intellisense anzuzeigen.
RBT

19

Die ConcatMethode gibt ein Objekt zurück, das implementiert wird, IEnumerable<T>indem ein Objekt zurückgegeben wird (nennen Sie es Cat), dessen Enumerator versucht, die beiden übergebenen aufzählbaren Elemente (nennen Sie sie A und B) nacheinander zu verwenden. Wenn die übergebenen Aufzählungen Sequenzen darstellen, die sich während der Lebensdauer von Cat nicht ändern und aus denen ohne Nebenwirkungen abgelesen werden kann, kann Cat direkt verwendet werden. Andernfalls kann es eine gute Idee zu nennen sein , ToList()auf Catund verwenden Sie das Ergebnis List<T>(die eine Momentaufnahme der Inhalte von A und B wird).

Einige Aufzählungen erstellen zu Beginn der Aufzählung einen Snapshot und geben Daten aus diesem Snapshot zurück, wenn die Auflistung während der Aufzählung geändert wird. Wenn B eine solche Aufzählung ist, wird jede Änderung an B, die auftritt, bevor Cat das Ende von A erreicht hat, in der Aufzählung von Cat angezeigt, Änderungen, die danach auftreten, jedoch nicht. Eine solche Semantik kann wahrscheinlich verwirrend sein; Wenn Sie einen Schnappschuss von Cat machen, können Sie solche Probleme vermeiden.


7

Sie können den folgenden Code für Ihre Lösung verwenden: -

public void Linq94() 
{ 
    int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 
    int[] numbersB = { 1, 3, 5, 7, 8 }; 

    var allNumbers = numbersA.Concat(numbersB); 

    Console.WriteLine("All numbers from both arrays:"); 
    foreach (var n in allNumbers) 
    { 
        Console.WriteLine(n); 
    } 
}

0
// The answer that I was looking for when searching
public void Answer()
{
    IEnumerable<YourClass> first = this.GetFirstIEnumerableList();
    // Assign to empty list so we can use later
    IEnumerable<YourClass> second = new List<YourClass>();

    if (IwantToUseSecondList)
    {
        second = this.GetSecondIEnumerableList();  
    }
    IEnumerable<SchemapassgruppData> concatedList = first.Concat(second);
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.