Выберите все уникальные комбинации одного списка без повторов, используя LINQ (часть 2)

Джон Скис отвечает на этот вопрос, Выберите все уникальные комбинации одного списка, без повторов, используя LINQ, работает великолепно.

Однако может ли кто-то сломать компонент по компоненту внутреннюю работу, как работает первый ответ:

List<int> slotIds = new List<int> {1, 2, 3};
var query = slotIds.SelectMany((value, index) => slotIds.Skip(index + 1),
                              (first, second) => new { first, second });

Ответ 1

Это примерно эквивалентно по концепции этому, хотя фактическая модель исполнения отличается, конечно, (ленивая и т.д.):

for (int i = 0; i < slotIds.Count; i++)
{
    int first = slotIds[i];
    for (int j = i + 1; j < slotIds.Count; j++)
    {
        int second = slotIds[j];
        results.Add(new { first, second });
    }
}

SelectMany, выполняющий проекцию из value и index, является способом использования как first, так и i для создания внутреннего цикла. Нам нужен индекс, чтобы мы могли пропускать значения index + 1, что эквивалентно циклу j, начинающемуся с i + 1 в приведенном выше коде.

Помогает ли это? Если нет, можете ли вы определить, какой бит запутывает?

EDIT: Aargh - я не понял, что другой вопрос, который вы говорили, начинался с этого кода! Я думаю, что это все же полезно, хотя, чтобы дать абзац ниже что-то, что можно повесить на...

Если вы поняли альтернативу (выражение запроса) моего ответа, то первая версия схожа, просто используя перегрузку SelectMany, которая позволяет использовать как значение, так и индекс во "внешней" последовательности.