假设我有列表列表。我想从给定的列表列表创建新列表,以便元素按照下面给出的示例顺序排列。
输入:-
List<List<int>> l = new List<List<int>>();
List<int> a = new List<int>();
a.Add(1);
a.Add(2);
a.Add(3);
a.Add(4);
List<int> b = new List<int>();
b.Add(11);
b.Add(12);
b.Add(13);
b.Add(14);
b.Add(15);
b.Add(16);
b.Add(17);
b.Add(18);
l.Add(a);
l.Add(b);
输出(列表):-
1
11
2
12
3
13
4
14
15
16
并且输出列表必须不包含超过 10 个
元素。
我目前正在使用 foreach inside while
执行此操作,但我想知道如何使用 LINQ
执行此操作。
int loopCounter = 0,index=0;
List<int> o=new List<int>();
while(o.Count<10)
{
foreach(List<int> x in l)
{
if(o.Count<10)
o.Add(x[index]);
}
index++;
}
谢谢。
使用接收项目索引的 SelectMany
和 Select
重载。这将用于应用所需的排序。 SelectMany
的用途是展平嵌套集合级别。最后,应用 Take
仅检索所需数量的项目:
var result = l.SelectMany((nested, index) =>
nested.Select((item, nestedIndex) => (index, nestedIndex, item)))
.OrderBy(i => i.nestedIndex)
.ThenBy(i => i.index)
.Select(i => i.item)
.Take(10);
或者在查询语法中:
var result = (from c in l.Select((nestedCollection, index) => (nestedCollection, index))
from i in c.nestedCollection.Select((item, index) => (item, index))
orderby i.index, c.index
select i.item).Take(10);
如果使用 C# 6.0 和之前的项目改为匿名类型:
var result = l.SelectMany((nested, index) =>
nested.Select((item, nestedIndex) => new {index, nestedIndex, item}))
.OrderBy(i => i.nestedIndex)
.ThenBy(i => i.index)
.Select(i => i.item)
.Take(10);
解释为什么单独使用 Zip
是不够的:zip 相当于对第二个集合执行 join
操作到第一个,其中
加入的属性是索引。因此,只有第一个集合中存在的项目,如果它们在第二个集合中有匹配项,才会出现在结果中。
下一个选项是考虑 left join
,它将返回第一个集合中的所有项目,并在第二个集合中匹配(如果存在)。在描述的情况下,OP 正在寻找 full outer join
的功能 - 尽可能获取集合和匹配项的所有项目。