Nikos Baxevanis
Nikos Baxevanis

Reputation: 11201

LINQ, Grouping on IEnumerable<object[]>

I have the following elements (could be more than two):

new[] { new[] { "A" }, new[] { "B", "C" } }
new[] { new[] { "D" }, new[] { "E", "F" } }

I want to group them as follow:

"A", "D"

"B", "C", "E", "F"

What is the most optimum way (or at least a good way)?

Is it possible to store, somehow, that on the first pair "D" (and on second pair E" and "F") were not in the same array at the beginning?

Upvotes: 0

Views: 950

Answers (2)

svick
svick

Reputation: 244777

Assuming you have the two in a collection:

var collections = new[]
{
    new[] { new[] { "A" }, new[] { "B", "C" } },
    new[] { new[] { "D" }, new[] { "E", "F" } }
};

var result = from first in collections
             from second in first.Select((x, i) => new {x, i})
             from third in second.x
             group third by second.i;

The result is IEnumerable<IGrouping<int, string>>, which means each member is a collection of strings that also has an int key. Note that the result may not be sorted, so the group for 1 may come first. If you don't want that, add orderby to the end of the query.

Upvotes: 1

TomZ
TomZ

Reputation: 421

I just ran into this yesterday. Not the most readable, but it accomplishes the objective.

new [] { 
    new[] { new[] { "A" }, new[] { "B", "C" } },
    new[] { new[] { "D" }, new[] { "E", "F" } }
}.SelectMany((x, arrayPos) => x.Select((y, itemPos) => new { y, arrayPos, itemPos }))
    .GroupBy(x => new { x.itemPos })
.Select(x => x.SelectMany(y => y.y.Select(z => new { z, y.arrayPos })))

The arrayPos value will indicate the original position.

Upvotes: 1

Related Questions