tags:

views:

932

answers:

6

If I have variable of type IEnumerable<List<string>> is there a LINQ statement or lambda expression I can apply to it which will combine the lists returning an IEnumerable<string>?

+12  A: 

SelectMany - i.e.

        IEnumerable<List<string>> someList = ...;
        IEnumerable<string> all = someList.SelectMany(x => x);

For each item in someList, this then uses the lambda "x => x" to get an IEnumerable<T> for the inner items. In this case, each "x" is a List<T>, which is already IEnumerable<T>.

These are then returned as a contiguous block. Essentially, SelectMany is something like (simplified):

static IEnumerable<TResult> SelectMany<TSource, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, IEnumerable<TResult>> selector) {

    foreach(TSource item in source) {
      foreach(TResult result in selector(item)) {
        yield return result;
      }
    }
}

Although that is simplified somewhat.

Marc Gravell
+1  A: 

Not exactly a single method call, but you should be able to write

var concatenated = from list in lists from item in list select item;

Where 'lists' is your IEnumerable<List<string>> and concatenated is of type IEnumerable<string>.

(Technically this is a single method call to SelectMany - it just doesn't look like it was all I meant by the opening statement. Just wanted to clear that up in case anyone got confused or commented - I realised after I'd posted how it could have read).

Greg Beech
A: 

Make a simple method. No need for LINQ:

IEnumerable<string> GetStrings(IEnumerable<List<string>> lists)
{
   foreach (List<string> list in lists)
   foreach (string item in list)
   {
     yield return item;
   }
 }
VVS
And no reason not to use it if you are using .NET 3.5 (which we can assume from the OP), or C# 3.0 with .NET 2.0 and LinqBridge.
Marc Gravell
@Marc: You're right, especially if there's an easy "linqish" way. Sometimes people just try hard to do something the LINQ way and make simple things harder to grasp.
VVS
A: 

Using LINQ expression...

IEnumerable<string> myList = from a in (from b in myBigList
                                        select b)
                             select a;

... works just fine. :-)

b will be an IEnumerable<string> and a will be a string.

Jarrett Meyer
A: 

Here's another LINQ query comprehension.

IEnumerable<string> myStrings =
  from a in mySource
  from b in a
  select b;
David B
A: 

How about

myStrings.SelectMany(x => x)
JaredPar
good solution, with small typo
David B
Thanks. Updated the typo
JaredPar