c# -基于与另一个列表的部分交集从列表中选择特定的项(Linq + Lambda)
本文关键字:列表 选择 Lambda Linq 另一个 | 更新日期: 2023-09-27 17:51:02
我有两个列表:
List<objA> list1
List<objB> list2
class objA
{
string Name;
}
class objB
{
string Name;
bool SomeProp;
}
使用c# linq/lambda,我想选择所有具有Name属性等于第二个obj (list1)的Name属性的objA对象。Name == list2.Name)并检查objB的另一个属性(list2. Name)。SomeProp == true).
我建议使用join:
from a in list1
join b in list2 on a.Name equals b.Name
where b.SomeProp
select a
λ的语法:
list1.Join(listb.Where(b => b.SomeProp),
a => a.Name, b => b.Name, (a,b) => a)
注意:这样您将避免为list1中的每个项枚举list2集合(具有Any
的解决方案)
为了显示两种解决方案之间的区别-让我们看看将linq转换为普通循环后它们是什么样子。第一个是
list1.Where(a => list2.Any(b => b.Name == a.Name && b.SomeProp))
等于
foreach(var a in list1)
{
foreach(var b in list2)
{
if (a.Name == b.Name && b.SomeProp)
{
yield return a;
break;
}
}
}
正如你所看到的——它有嵌套循环,复杂度是O(N*M)。通过join,我们为内部序列创建了查找:
Lookup<string, objB> lookup = list2.Where(b => b.SomeProp).ToLookup(b => b.Name);
foreach(var a in list1)
{
Grouping<string, objB> g = lookup.GetGrouping(a.Name);
if (g == null)
continue;
foreach(var b in g)
yield return a;
}
这里的差异是查找中的搜索-这是O(1)操作。总复杂度为0 (M +N)
应该这样做:
list1.Where(a => list2.Any(b => b.Name == a.Name && b.SomeProp));