views:

184

answers:

7

I have for example 5 List all of the same type. Can I simply do

List<T> newset = List1.Concat(List2).Concat(List3).Concat(List4).....
+5  A: 

Yes, you can do that.

List<Thing> newSet = List1.Concat(List2).Concat(List3).Concat(List4).ToList();
David Morton
+1  A: 

You certainly can do that, though it may not be incredibly efficient.

As stated by other answers, don't forget to add .ToList() to the end of your line of code, or use List1.AddRange(List2); List1.AddRange(List3); ... for added efficiency.

Aaron
+13  A: 

You can do this (although you need .ToList() at the end).

However, it would be (slightly) more efficient to generate a single list, and use AddRange to add in each list. Just initialize the list with the total size of all of your lists, then call AddRange repeatedly.

You might want to consider doing something like:

public List<T> ConcatMultiple<T>(this List<T> list, params[] ICollection<T> others)
{
    List<T> results = new List<T>(list.Count + others.Sum(i => i.Count));
    results.AddRange(list);
    foreach(var l in others)
        results.AddRange(l);
    return results;
}

Then calling via:

List<MyClass> newset = List1.ConcatMultiple(List2, List3, List4);
Reed Copsey
Seems a bit strange to make that an extension method of a specific list, considering it returns a completely new list and doesn't affect the main list in any way.
Ilia Jerebtsov
@Ilia: It doesn't seem strange to me, as it's really no different than Enumerable.Concat in terms of usage: http://msdn.microsoft.com/en-us/library/bb302894.aspx
Reed Copsey
+4  A: 

you can, but do not forget to append .ToList(); in the end. also you can call newset.AddRange(ListX); i think it is better in terms of performance

Andrey
+1  A: 

For variable list count:

IEnumerable<T> enumerable = Enumerable.Empty<T>();
foreach (List<T> list in [whatever])
   enumerable = enumerable.Concat(list);

At the end you could add a "ToList()" if you want a rely List:

List<T> list = enumerable.ToList();

However, this might not be neeeded.

winSharp93
+1  A: 

of you can use an union in LINQ if it is a real union that you want to do ofcourse...

Tim Mahy
+1  A: 

If you want to concatenate an arbitrary (previously unknown) number of lists, then you may need to concatenate a collection of lists. Probably the easiest way to do this would be to use the SelectMany operator (or nested from clauses in LINQ query):

IEnumerable<List<int>> lists = /* get list of lists */;
List<int> result = lists.SelectMany(e => e).ToList();

The SelectMany operator calls the given function for every element of the input list (which is a list) and then concatenates all the resulting lists (the actual lists from your input list of lists). Alternatively using the LINQ query syntax:

List<int> result = (from l in lists
                    from e in l select e).ToList();

I believe that the C# compiler may actually optimize this, so that it doesn't iterate over all the individual elements (and does the same thing as the explicit version above). If you have a known number of lists, you can of course write:

List<int> result = (from l in new[] { list1, list2, list3, list4 }
                    from e in l select e).ToList();

It is not as elegant as defining your own method exactly for this purpose, but it shows how powerful the LINQ query syntax is.

Tomas Petricek