C# 使用 LINQ 通过一个属性比较两个列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17323804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Compare Two Lists Via One Property Using LINQ
提问by Coltech
Say I have the following:
说我有以下几点:
class Widget1{
public int TypeID { get; set; }
public string Color { get; set; }
}
class Widget2
{
public int TypeID { get; set; }
public string Brand { get; set; }
}
private void test()
{
List<Widget1> widgets1 = new List<Widget1>();
List<Widget2> widgets2 = new List<Widget2>();
List<Widget1> widgets1_in_widgets2 = new List<Widget1>();
//some code here to populate widgets1 and widgets2
foreach (Widget1 w1 in widgets1)
{
foreach (Widget2 w2 in widgets2)
{
if (w1.TypeID == w2.TypeID)
{
widgets1_in_widgets2.Add(w1);
}
}
}
}
I am using two foreach loops to compare the lists by TypeID to populate a third list. Is there any other way using LINQ to compare these two lists via the TypeID? Perhaps using Interstect or some other function?
我使用两个 foreach 循环按 TypeID 比较列表以填充第三个列表。有没有其他方法使用 LINQ 通过 TypeID 比较这两个列表?也许使用 Interstect 或其他一些功能?
采纳答案by Servy
What you want here is a Join.
你想要的是一个Join.
var widgets1_in_widgets2 = from first in widgest1
join second in widgets2
on first.TypeID equals second.TypeID
select first;
Intersectcan be more or less thought of as a special case of Joinwhere the two sequences are of the same type, and can thus be applied for equality instead of needing a projection for each type to generate a key to compare. Given your case, Intersectisn't an option.
Intersect可以或多或少地被认为是Join两个序列属于相同类型的特殊情况,因此可以应用于相等而不需要每个类型的投影来生成要比较的键。鉴于你的情况,Intersect不是一个选择。
If a particular ID is duplicated in your second set and you don't want the item to be duplicated in the results then you can use a GroupJoininstead of a Join:
如果特定 ID 在您的第二组中重复,并且您不希望该项目在结果中重复,则可以使用 aGroupJoin代替 a Join:
var widgets1_in_widgets2 = from first in widgest1
join second in widgets2
on first.TypeID equals second.TypeID
into matches
where matches.Any()
select first;
回答by Heinzi
Join has the drawback that your results might be duplicated if widgets1 or widgets2 contains elements with the same TypeID more than one (which also applies to your original code, by the way).
Join 有一个缺点,如果 widgets1 或 widgets2 包含多个具有相同 TypeID 的元素(顺便说一下,这也适用于您的原始代码),您的结果可能会重复。
The following will do exactly what you want: Return all elements from widgets1 for which an element with a corresponding TypeID exists in widgets2.
以下将完全按照您的要求执行:返回widgets1 中所有具有对应TypeID 的元素存在于widgets2 中的元素。
widgets1_in_widgets2 = (from w1 in widgets1
where widgets2.Any(w2 => w1.TypeID == w2.TypeID)
select w1).ToList()
回答by Anirudha
You can do this
你可以这样做
widgets2.Where(y=>widget1.Any(z=>z.TypeID==y.TypeID));
回答by Soumya Das
Try using overload of "Where"
尝试使用“Where”的重载
var isMatch = !widgets1.Where((w1, index) => w1.TypeId == widgets2[index].TypeId)).Any();
回答by Bruno Gozzi
I like this solution because it is simple to read in the code.
我喜欢这个解决方案,因为它很容易读入代码。
bool result = firstList.All(o => secondList.Any(w => w.Prop1 == o.Prop1 && w.Prop2 == o.Prop2));
See the full example in fiddle: Fiddle example comparation
查看小提琴中的完整示例:小提琴示例比较

