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.