我有两个列表
的List1 只有两个属性。 不能使用Dictionary,因为可能有重复的键。 Property1和Property2的组合是唯一的。
public class List1
{
public string Property1 { get; internal set; }
public string Property2 { get; internal set; }
}
public class List2
{
public string Property1 { get; internal set; }
public string Property2 { get; internal set; }
public string Property3 { get; internal set; }
}
List<List1> mylist1 = new List<List1>() {
new List1() {Property1="664",Property2="Ford" },
new List1() {Property1="665",Property2="Ford" },
new List1() {Property1="664",Property2="Toyota" },
};
List<List2> mylist2 = new List<List2>() {
new List2() {Property1="664",Property2="Ford" ,Property3="USA"},
new List2() {Property1="665",Property2="Ford" ,Property3="USA"},
new List2() {Property1="664",Property2="Toyota" ,Property3="USA"},
new List2() {Property1="666",Property2="Toyota" ,Property3="USA"},
};
我需要获取mylist1和mylist2中的匹配项。匹配应仅在Property1和Property2上进行。在比较期间,可以忽略mylist2中的Property3。
目前我使用
var matchingCodes = mylist1.Where(l1 => mylist2.Any(l2 => (l2.Property1 == l1.Property1 && l2.Property2==l1.Property2))).ToList();
完美无缺。但有没有更好的方法/最快的方法呢?
我可以将List1更改为任何其他类型。但不是List2。
答案 0 :(得分:3)
在Linq中执行此操作的最简单方法是使用Join
或GroupJoin
这样的方法相对较快,或者至少快于您的方法:
List<List1> matchingCodes = mylist1.GroupJoin(mylist2,
l1 => new { l1.Property1, l1.Property2 },// Define how the key from List1 looks like
l2 => new { l2.Property1, l2.Property2 },// Define how the key from List2 looks like
// Define what we select from the match between list1 and list2
(l1Item, l2Items) => l1Item).ToList();
简化,这会创建两个字典,然后将它们连接在一起。
GroupJoin
在这里工作得更好,因为它为您提供了List1中的项目和来自list2的所有匹配项。
常规Join
将从List2返回每个匹配的List1中相同的项目。
另见Enumerable.GroupJoin (C# Reference)
注意这相当于@octavioccl's answer。 此示例还假设,两个类的属性名称相同。如果他们不是你必须修改他们的键选择器如此:
l1 => new { A=l1.Foo, B=l1.Bar},
l2 => new { A=l2.Herp, B=l2.Derp},
答案 1 :(得分:3)
你也可以加入:
var query= from l in mylist1
join e in mylist2 on new {Property1=l.Property1,Property2=l.Property2} equals new {Property1=e.Property1,Property2=e.Property2}
select l;
答案 2 :(得分:2)
您正尝试在LINQ中对数据列表执行set
操作。有四个LINQ函数调用可用于使当前代码更清晰,更简洁。这些操作是:
您正在寻找的是Intersect,它是
返回在两个单独的集合中找到的相同值集 Source
最后,如果您总是要使用这些特定属性来检测相等性和/或唯一性,则需要为List1和/或List2类重写Equals
。这将取决于Intersect左侧的人(在。之前的变量)和谁在Intersect的右侧(传递给函数的变量)。
Here is a SO answer了解如何覆盖Equals
函数,如果您不知道如何执行此操作。巧合的是,它也有一个Intersect
例子。
答案 3 :(得分:0)
这两个属性都是字符串,因此您只需创建一个字典,其中包含这些属性的串联,其值为实际项。
因此,对于其他列表中的每个项目,您只需在字典中查找其属性的串联,如果匹配,则与找到的项目进行比较