How to merge a list of lists with same type of items to a single list of items?
Asked Answered
A

4

295

The question is confusing, but it is much more clear as described by the following code:

   List<List<T>> listOfList;
   // add three lists of List<T> to listOfList, for example
   /* listOfList = new {
        { 1, 2, 3}, // list 1 of 1, 3, and 3
        { 4, 5, 6}, // list 2
        { 7, 8, 9}  // list 3
        };
   */
   List<T> list = null;
   // how to merger all the items in listOfList to list?
   // { 1, 2, 3, 4, 5, 6, 7, 8, 9 } // one list
   // list = ???

Not sure if it possible by using C# LINQ or Lambda?

Essentially, how can I concatenate or "flatten" a list of lists?

Arrestment answered 27/7, 2009 at 22:41 Comment(0)
P
619

Use the SelectMany extension method

list = listOfList.SelectMany(x => x).ToList();
Pradeep answered 27/7, 2009 at 22:42 Comment(5)
I wonder how many folks have written their own "Flatten" extension not realizing how SelectMany works?Perretta
Why is x => x needed for this to work? I usually see things like x = > x +1 but not x = > x.Lasseter
@Lasseter SelectMany is used to take an IEnumerable of TSources, convert each TSource in the list into an IEnumerable of TResults, then concatenate all those IEnumerables into one big one. In this case you have a list of lists to start, so if you want to concatenate them the function to map from a TSource (which is an IEnumerable of TResults) to an IEnumerable of TResults is the identity function (x => x). This is really just a special case where you don't need the extra step of turning each TSource into a list, because it's already a list.Dotard
@Pradeep can we apply this logic to list<list<list<T>>> ?Smallish
@TusharKukreti Sure, just use list.SelectMany(x => x.SelectMany(y => y)).ToList();Astroid
M
16

Here's the C# integrated syntax version:

var items =
    from list in listOfList
    from item in list
    select item;
Magdala answered 27/7, 2009 at 22:53 Comment(3)
Little bit confusing, but nice. How this? var items = from item in (from list in listOflist select list) select itemArrestment
The 'double from' is the same as SelectMany ... SelectMany is probably the most powerful of the LINQ methods (or query operators). To see why, Google "LINQ SelectMany Monad" and you'll discover more than you'll want to know about it.Felty
Don't include the quotes when googling "LINQ SelectMany Monad" or it'll just direct you back to here.Kerwon
A
15

Do you mean this?

var listOfList = new List<List<int>>() {
    new List<int>() { 1, 2 },
    new List<int>() { 3, 4 },
    new List<int>() { 5, 6 }
};
var list = new List<int> { 9, 9, 9 };
var result = list.Concat(listOfList.SelectMany(x => x));

foreach (var x in result) Console.WriteLine(x);

Results in: 9 9 9 1 2 3 4 5 6

Adalai answered 27/7, 2009 at 22:51 Comment(1)
Or you could use list.AddRange() instead of Concat() to add the merged items to the existing list.Particulate
G
13

For List<List<List<x>>> and so on, use

list.SelectMany(x => x.SelectMany(y => y)).ToList();

This has been posted in a comment, but it deserves a separate answer in my opinion.

Greasy answered 11/1, 2019 at 12:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.