Kevin Le Kevin Le - 3 months ago 14
C# Question

Second lambda in SelectMany

Was curiouis and looked around for a LINQ permutation solution and found one here:

What is the best way to find all combinations of items in an array?

Here is the code in question:

static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> list, int length)
{
if (length == 1) return list.Select(t => new T[] { t });
return GetPermutations(list, length - 1)
.SelectMany(t => list.Where(o => !t.Contains(o)),
(t1, t2) => t1.Concat(new T[] { t2 }));
}


I understand the solution for the most part, but am unsure what
t1
and
t2
refer to in the SelectMany. I know
t1
is a Enumerable and
t2
is a T. Any explanations would be great, thanks!

Edit*

Oops, I was looking at the wrong SelectMany docs. The correct one signature is here https://msdn.microsoft.com/en-us/library/bb534631(v=vs.110).aspx.

Answer

That second lambda is the resultSelector and allows for modifications of the selected collection (t2) depending on the instance that owns the collection (t1).

In your specific example t1 is a permutation of list and t2 is an element of all the elements from list that are not part of t1.

Hence (t1, t2) => t1.Concat(new T[] { t2 }) is used to yield the next "generation" of permutations from a given permutation t1 and the so far unused elements from list.

Example:

Let list be { 1, 2, 3, 4 } and let t1 be { 1, 2 }.

Then the collectionSelector will select all elements from list not inside t1, i.e. { 3, 4 }, and the resultSelector will append each of those elements to t1 once.

Thus yielding the permutations { 1, 2, 3 } and { 1, 2, 4 }.