使用LINQ选择单个列表的所有唯一组合,不重复(第二部分)

6

约翰·斯基特(John Skeets)对这个问题的回答,使用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 });

2
为什么不在那个答案下面的评论中提出这个问题呢? - H H
1个回答

6

这个概念上大致相当于这个,尽管实际的执行模型当然是不同的(懒惰等):

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 的投影函数从 valueindex 接收参数,是同时使用 firsti 来创建内部循环的一种方式。我们需要索引来跳过 index + 1 个值,这相当于上面代码中的 j 循环从 i + 1 开始。
这样清楚吗?如果还有不理解的地方,请指出是哪里令您困惑。
编辑:啊!我没有意识到您提到的另一个问题是从这段代码开始的!尽管如此,我认为这仍然有用,可以让下面的段落有所依据......
如果您理解了我的另一篇答案中的可选语法版本,那么第一篇答案类似,只不过使用了 SelectMany 的重载版本,该版本允许您在“外部”序列中同时使用值和索引。

所以你正在使用这个重载版本的SelectMany,http://msdn.microsoft.com/en-us/library/bb534732.aspx,所以collectionSelector创建了“内部循环”,即{2,index=1} {3,index=2},然后该结果提供给resultSelector(第二个lambda函数)?我理解你的其他示例,我认为我的困惑在于lambda函数以及第二个lambda函数如何构建列表。 - Seth
@Seth:集合选择器是获取此答案中代码中ifirst等效值的部分。然后在resultSelector中使用这些值(即i和first)。 - Jon Skeet

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