Select all unique combinations of a single list, with no repeats, using LINQ (Part 2)
John Skeets回答这个问题,选择一个列表的所有唯一组合,不重复,使用Linq,效果非常好。
但是,是否有人可以将第一个答案如何工作的内部工作按组件分解:
1 2 3
| List <int> slotIds = new List <int> {1, 2, 3};
var query = slotIds .SelectMany((value, index ) => slotIds .Skip(index + 1),
(first, second ) => new { first, second }); |
虽然实际的执行模型当然不同(lazy等),但它在概念上大致等同于此:
1 2 3 4 5 6 7 8 9
| 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 });
}
} |
从value和index中取投影的SelectMany是一种利用first和i两种方法制作内环的方法。我们需要索引以便跳过index + 1值,这相当于上面代码中从i + 1开始的j循环。
有帮助吗?如果没有,你能指出哪一位是令人困惑的吗?
编辑:啊-我还没意识到你提到的另一个问题是从这段代码开始的!不过,我认为给下面的段落一些东西留点时间还是有用的…
如果您理解我的答案的可选(查询表达式)版本,那么第一个版本是类似的,只是使用了SelectMany的重载,它允许您在"外部"序列中同时使用值和索引。
- 因此,您使用的是selectmany的这个重载版本msdn.microsoft.com/en-us/library/bb534732.aspx,所以collectionselector创建了"内部循环",即123; 2,index=1 3,index=2,结果为resultsselector(第二个lambda函数)提供了源?我了解您的其他示例,我认为我的困惑在于lambda函数以及第二个lambda函数如何构建列表。
- @seth:集合选择器是在这个答案的代码中得到与i和first等价的位。这些值(i和first)随后在resultSelector中使用。