1

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.

Community
  • 1
  • 1
Kevin Le
  • 846
  • 8
  • 17
  • 1
    What did you find in the documentation for `SelectMany` and how did it fail to answer your question? – Servy Aug 30 '16 at 15:38
  • I read the msdn docs for `SelectMany` at https://msdn.microsoft.com/en-us/library/bb534336(v=vs.110).aspx but the examples are pretty simple and I understand those. To clarify, I understand SelectMany is used to flatten collections, but after the flattening, what does t1, t2 refer to? – Kevin Le Aug 30 '16 at 15:44
  • 2
    You're looking at the wrong documentation. https://msdn.microsoft.com/en-us/library/bb534631(v=vs.110).aspx – recursive Aug 30 '16 at 15:49
  • That would do it, makes much more sense now. Thanks all! – Kevin Le Aug 30 '16 at 15:57

1 Answers1

1

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 }.

Good Night Nerd Pride
  • 8,245
  • 4
  • 49
  • 65