使用LINQ选择单个列表中的所有唯一组合,不重复。

13

我有一个数字列表,需要使用LINQ查询创建该列表中所有可能的唯一组合,不重复地使用列表中的数字。例如,如果列表为{1, 2, 3},则组合将是1-21-32-3

我目前使用两个for循环来实现:

for (int i = 0; i < slotIds.Count; i++)
{
    for (int j = i + 1; j < slotIds.Count; j++)
    {
        ExpressionInfo info1 = _expressions[i];
        ExpressionInfo info2 = _expressions[j];

        // etc...
    }
}

是否可以将这两个 for 循环转换为 LINQ?

谢谢。


组合总是有序的,对吗? - kame
1个回答

32

当然可以 - 你可以在一次调用中使用嵌套的 Skip 调用来使用 SelectMany:

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

这里提供一种替代方案,它不使用 SelectMany 如此晦涩难懂的重载:

var query = from pair in slotIds.Select((value, index) => new { value, index })
            from second in slotIds.Skip(pair.index + 1)
            select new { first = pair.value, second };

这些基本上做的是同样的事情,只是以稍微不同的方式呈现。

这里有另一种选项,它更接近于您的原始选择:

var query = from index in Enumerable.Range(0, slotIds.Count)
            let first = slotIds[index] // Or use ElementAt
            from second in slotIds.Skip(index + 1)
            select new { first, second };

请参考以下讨论关于奇特的第一种解决方案:https://dev59.com/fVzUa4cB1Zd3GeqP7Np3 - Thilo
1
@David:我不相信.NET中的任何集合在多次迭代时返回元素的顺序会有所不同,而且没有任何更改。我们不关心顺序是什么,只要它是一致的即可。 - Jon Skeet
糟糕,那么我们的某个地方出现了最奇怪的错误,谢谢,我会删除我的两个评论:p - David
1
@David:如果你能重现这个问题,一定要创建一个新的问题,并用链接提醒我 :) - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接