Comment concaténer deux IEnumerable <T> en un nouveau IEnumerable <T>?

201

J'ai deux instances de IEnumerable<T>(avec le même T). Je veux une nouvelle instance IEnumerable<T>dont la concaténation des deux.

Existe-t-il une méthode intégrée dans .Net pour le faire ou dois-je l'écrire moi-même?

Samuel Rossille
la source
9
Vous souhaiterez peut-être mettre en signet code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b .
C-Pound Guru

Réponses:

332

Oui, LINQ to Objects prend en charge ceci avec Enumerable.Concat:

var together = first.Concat(second);

NB: Si firstou secondêtre nul, vous recevrez un ArgumentNullException. Pour éviter cela et traiter les valeurs nulles comme vous le feriez pour un ensemble vide, utilisez l'opérateur de coalescence null comme ceci:

var together = (first ?? Enumerable.Empty<string>()).Concat(second ?? Enumerable.Empty<string>()); //amending `<string>` to the appropriate type
Jon Skeet
la source
1
J'oublie toujours de chercher des méthodes d'extension, tx.
Samuel Rossille
10
@SamuelRossille N'oubliez pas non plus que les noms des actions que vous souhaitez effectuer sont probablement proches s'ils ne sont pas exactement appelés ce que vous recherchez. Parcourez toujours IntelliSense, vous apprenez beaucoup.
Adam Houldsworth
3
Est-ce mauvais de faire second = premier. Concat (deuxième)? aurons-nous des problèmes de concurrence?
user2934433
4
@ user2934433: Non, c'est très bien.
Jon Skeet
2
Juste une petite note. Il est nécessaire d'importer l' using System.Linq espace de noms en haut du fichier de code pour voir la méthode d'extension souhaitée dans l'IDE intellisense.
RBT
19

La Concatméthode retournera un objet qui implémente IEnumerable<T>en renvoyant un objet (appelez-le Cat) dont l'énumérateur tentera d'utiliser les deux éléments énumérables transmis (appelez-les A et B) dans l'ordre. Si les énumérations transmises représentent des séquences qui ne changeront pas pendant la durée de vie de Cat et qui peuvent être lues sans effets secondaires, alors Cat peut être utilisé directement. Dans le cas contraire, il peut être une bonne idée d'appeler ToList()sur Catet utiliser le résultat List<T>(qui représentera un aperçu du contenu de A et B).

Certains énumérateurs prennent un instantané au début de l'énumération et renvoient des données à partir de cet instantané si la collection est modifiée pendant l'énumération. Si B est un tel énumérable, alors tout changement à B qui se produit avant que Cat n'ait atteint la fin de A apparaîtra dans l'énumération de Cat, mais les changements qui se produisent après cela ne le seront pas. Une telle sémantique peut être source de confusion; prendre un instantané de Cat peut éviter de tels problèmes.

supercat
la source
7

Vous pouvez utiliser le code ci-dessous pour votre solution: -

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); 
    } 
}
Jay Shukla
la source
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);
}
Hasse
la source