如何使用LINQ合并两个列表?

29

环境:.NET4 C#

大家好,

我想把这两个列表合并成一个:{ "A", "B", "C", "D", "1", "2", "3" }

{ "A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3", "D1", "D2", "D3" }

显然,我可以使用嵌套循环。但我想知道LINQ是否能够帮助我。 就我所了解的,Zip()在这种情况下不适用,对吧?

TIA,


2
通常在使用LINQ开始类似的工作时,询问“如果这些是数据库中的表,我该如何处理”会很有益。 - SWeko
3个回答

59

当你想要形成两个列表的笛卡尔积时,请使用SelectMany:

aList.SelectMany(a => bList.Select(b => a + b))


1
这太优雅了!这就是我喜欢LINQ的原因! - Chris
我喜欢这个,但想要合并两个集合,有点像 SQL 的 select t1,t2,所以稍微修改一下就变成了:aList.SelectMany(a => bList.Select(b => new {a, b})) - David Hyde

37

本质上,你想生成一个笛卡尔积,然后连接每个2元组的元素。最简单的方法是使用查询语法:

var cartesianConcat = from a in seq1
                      from b in seq2
                      select a + b;

1
正如Jon所指出的那样,就我而言,在(撰写本文时)的三个答案中,我认为这个答案最易读。实际上,它与我们在没有LINQ的情况下使用的嵌套循环相匹配,这可能是其他人不选择此答案的理由。但当然,我很想能够将这3个答案标记为已接受 :-) - Serge Wautier

26

SelectMany绝对是正确的方法,无论是使用多个"from"子句还是直接调用,但这里有一种替代Hightechrider使用它的方法:

var result = aList.SelectMany(a => bList, (a, b) => a + b);

我个人认为这种写法更容易理解,因为它更接近“多重来源”版本:对于“aList”中的每个“a”,我们都会产生一个新的序列 - 在这种情况下,它始终是“bList”。对于由笛卡尔积产生的每个(a,b)对,我们将其投影到一个结果中,该结果只是两个序列的连接。

只是为了明确起见:这两种方法都可以工作。我只是更喜欢这种方式 :)

至于这是否比查询表达式语法更清晰......我不确定。当只涉及使用单个运算符时,我通常使用方法调用,但对于Join、GroupJoin、SelectMany和GroupBy,查询表达式确实简化了事情。尝试一下两种方法,看看哪种更容易阅读 :)


9
嗨,Jon,我一直想问你,你在 Stack Overflow 上有多经常出没? :) - The_Butcher
2
@The_Butcher:http://meta.stackexchange.com/questions/555/why-does-jon-skeet-never-sleep/566#566 - Callum Rogers

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