Come concatenare due IEnumerable <T> in un nuovo IEnumerable <T>?


201

Ho due casi di IEnumerable<T>(con lo stesso T). Voglio una nuova istanza di IEnumerable<T>cui è la concatenazione di entrambi.

Esiste un metodo integrato in .Net per farlo o devo scriverlo da solo?


9
È possibile che si desideri contrassegnare il codice code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b .
— C-Pound Guru

Risposte:


332

Sì, LINQ to Objects lo supporta con Enumerable.Concat:

var together = first.Concat(second);

NB: Qualora firsto secondessere nullo che avrebbe ricevuto un ArgumentNullException. Per evitare questo e trattare i valori nulli come se fosse un set vuoto, utilizzare l'operatore di coalescenza null in questo modo:

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

1
Ho sempre dimenticato di cercare metodi di estensione, tx.
— Samuel Rossille,

10
@SamuelRossille Inoltre, non dimenticare che i nomi delle azioni che desideri eseguire sono probabilmente vicini se non chiamati esattamente ciò che stai cercando. Sfoglia sempre IntelliSense, impari molto.
— Adam Houldsworth,

3
È male fare second = first.Concat (secondo)? avremo problemi di concorrenza?
— user2934433

4
@ user2934433: No, va assolutamente bene.
— Jon Skeet,

2
Solo una breve nota. È necessario importare lo using System.Linq spazio dei nomi nella parte superiore del file di codice per visualizzare il metodo di estensione desiderato nell'IDE intellisense.
— RBT

19

Il Concatmetodo restituirà un oggetto che implementa IEnumerable<T>restituendo un oggetto (chiamalo Cat) il cui enumeratore tenterà di utilizzare i due elementi enumerabili passati (chiamali A e B) in sequenza. Se gli enumerabili passati rappresentano sequenze che non cambieranno durante la vita di Cat e che possono essere lette senza effetti collaterali, allora Cat può essere usato direttamente. Altrimenti, può essere una buona idea per chiamare ToList()sulla CatUtilizzando risultante List<T>(che rappresenterà un'istantanea dei contenuti di A e B).

Alcuni enumerabili eseguono un'istantanea quando inizia l'enumerazione e restituiranno i dati da quella istantanea se la raccolta viene modificata durante l'enumerazione. Se B è un tale elenco, allora qualsiasi modifica a B che si verifica prima che Cat abbia raggiunto la fine di A verrà mostrata nell'enumerazione di Cat, ma le modifiche che si verificano successivamente non lo faranno. Tale semantica può essere probabilmente fonte di confusione; scattare un'istantanea di Cat può evitare tali problemi.


7

È possibile utilizzare il codice seguente per la soluzione: -

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);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.