views:

275

answers:

4
public class Buddy
 {
  public string[] Sayings;
 }


Buddy one = new Buddy();
  one.Sayings = new[] {"cool", "wicked", "awesome"};

  Buddy two = new Buddy();
  two.Sayings = new[] {"bad", "lame", "boring"};

  Buddy[] buddies = new[] {one, two};

  IEnumerable<string[]> something =
   from b in buddies
   select b.Sayings;

So basically I would like to get a single array or list that contains {"cool, wicked, awesome, "bad", "lame", "boring"} the sayings for each Buddy using linq.

I tried everything I could think of and am starting to doubt it can be done with just a single linq expression. I could go through each buddy in buddies and do an addrange on the Sayings into a list but I figured since I am learning linq I would try it this way. Is it possible and if so how? This could also apply if I wanted to get some other objects inside of a Buddy in this case its just the list of strings.

+4  A: 

How about this:

var result2 = buddies.SelectMany(b => b.Sayings);
Jake Pearson
That works but what about if I have n number of buddies meaning I don't know the size of the collection. I forgot to mention the that the example only includes 2 buddy objects but in reality it could be 1000. I don't want to have to union each one with the next since the size is unknown.
ElvisLives
Sorry, there you go.
Jake Pearson
I was trying to work out why this wasn't acceptable and now it is the selected answer!
RichardOD
A: 

This should work ...

var buds = new [] { new Buddy { Sayings = new[] {"1","2","3"} },
                    new Buddy { Sayings = new[] {"4","5","6"} },
                    new Buddy { Sayings = new[] {"7","8","9"} } };


var res = buds.SelectMany( b => b.Sayings ).ToArray();
JP Alioto
A: 

     string[] a = new string[] {"a", "b", "c", "d"};
      string[] b = new string[] {"1", "2", "3"};

     var unioned = a.Union(b);
     foreach(string s in unioned)
      Console.WriteLine(s);
shahkalpesh
+2  A: 

Jakers is right - this is exactly what SelectMany does, in its simplest form. Alternative overloads allow you to get different results, e.g. including the "source" item in the projection as well.

Note that the query expression syntax for this is to have more than one from clause - each clause after the first one adds another call to SelectMany. Jakers code is similar to:

var result2 = from buddy in buddies
              from saying in buddy.Sayings
              select saying;

except the dot-notation version is more efficient - it only projects once. The above code compiles to:

var result2 = buddies.SelectMany(buddy => buddy.Sayings, 
                                 (buddy, saying) => saying);
Jon Skeet
If the Buddy[] array wasn't in the question code I would of done this (as it wasn't initially clear what was required):var result2 = one.Sayings.Concat(two.Sayings);
RichardOD