Lee Atkinson
Lee Atkinson

Reputation: 2181

Linq Transformations

I have an example class such as:

class Foo 
{ 
    Int32 A; 
    IEnumerable<Int32> B; 
}

Is it possible to transform an enumerable of Foo to an enumerable of Int32, which would include the A and the contents of B from all Foo's?

A non-LINQ solution would be:

var ints = new List<Int32>();
foreach (var foo in foos) {
    ints.Add(foo.A);
    ints.AddRange(foo.B);
}

The closest I could think of is:

var ints = foos.SelectMany(foo => var l = new List { foo.A }; l.AddRange(foo.B); return l);

But I wonder if there is a better solution that creating a temporary list?

Upvotes: 0

Views: 67

Answers (3)

Femaref
Femaref

Reputation: 61437

var ints = foos.SelectMany(f => f.B.Concat(new int[] { f.A}));

If you specifically need f.A before all elements from f.B:

var ints = foos.SelectMany(f => (new int[] { f.A }).concat(f.B));

Upvotes: 0

msarchet
msarchet

Reputation: 15242

as a List<Int32> per your non-Linq example

var ints = Foo.B.ToList().Add(Foo.A);

Lazy more Linq-ish solution

var ints = Foo.B.Concat(new Int32[] {Foo.A})

Upvotes: 0

BrokenGlass
BrokenGlass

Reputation: 160912

This should work:

var results = foos.SelectMany(f => f.B.Concat(new[] { f.A}));

Basic approach is to create a new enumeration with one element by creating an array with one element which is f.A, concatenating this to the existing enumeration of f.B and finally flatten the sequence with SelectMany()

Upvotes: 2

Related Questions