C# 如何比较linq中两个列表中的子项的属性
我有以下目标:C# 如何比较linq中两个列表中的子项的属性,c#,linq,C#,Linq,我有以下目标: public interface ITray { int OrderNo {get; set;} IEnumerable<ITrayItem> TrayItems {get;} } public interface ITrayItem { int Aisle {get; set;} } 公共接口ITray { int OrderNo{get;set;} IEnumerable TrayItems{get;} } 公共接口ITrayItem { int通道{get;
public interface ITray
{
int OrderNo {get; set;}
IEnumerable<ITrayItem> TrayItems {get;}
}
public interface ITrayItem
{
int Aisle {get; set;}
}
公共接口ITray
{
int OrderNo{get;set;}
IEnumerable TrayItems{get;}
}
公共接口ITrayItem
{
int通道{get;set;}
}
现在,我有两个列表对象
List<ITray> selectedTrays
List<ITray> poolTrays
列出所选光线
列出游泳池托盘
我要做的是针对poolTrays中的每个元素,比较所选托盘列表中的通道。如果所有通道的匹配,我想将其添加到要返回的托盘列表中。
我只是想让linq处理查询列表中集合的属性并返回列表中匹配的项
这就是我目前的情况:
List<int> selectedAisles = (from tray in selectedTrays
from item in tray.TrayItems
select item.Aisle).Distinct().ToList()
List<ITray> trayswithMatchingAisles =
(from t in poolTrays
from item in t.TrayItems
where selectedAisles.Contains(item.Aisle)
select t).ToList();
List selectedailes=(从selectedTrays中的托盘)
从tray.TrayItems中的项目
选择item.roadway).Distinct().ToList()
列出带有匹配岛的Tray=
(从池中的t开始)
从t.TrayItems中的项目
所选位置岛。包含(项目。过道)
选择t.ToList();
因此,如果我选择了托架A、B、C,托架中有通道
A[1,2,3]B[4,5,6]c[7,8,9]
然后,通道[7,9]中带有TrayItems的池托盘应成功返回,但列表中不应返回带有TrayItems[7,8,9,10]的池托盘
目前,我正在我的poolTray列表中传入(仅)[7,9],在我的Linq查询中返回了它的两个实例
var result = poolTrays.Where(x => selectedTrays.Any(z=>z.TrayItems.Select(y => y.Aisle)
.Intersect(x.TrayItems.Select(k => k.Aisle))
.Count() == x.TrayItems.Count()));
List<int> selectedAisles =
(from tray in selectedTrays
from item in tray.TrayItems
select item.Aisle)
.Distinct().ToList();
List<ITray> trayswithMatchingAisles =
(from t in poolTrays
where t.TrayItems.Select(i => i.Aisle)
.All(a => selectedAisles.Contains(a))
select t)
.ToList();
列出所选岛屿=
(从所选光线中的托盘)
从tray.TrayItems中的项目
选择项目(通道)
.Distinct().ToList();
列出带有匹配岛的Tray=
(从池中的t开始)
其中t.TrayItems.Select(i=>i.roach)
.All(a=>selectedailes.Contains(a))
选择t)
.ToList();
但这可以简化为:
List<ITray> trayswithMatchingAisles =
(from t in poolTrays
where t.TrayItems.Select(i => i.Aisle)
.All(a => selectedTrays
.SelectMany(s => s.TrayItems)
.Select(i => i.Aisle)
.Contains(a))
select t)
.ToList();
列出带有匹配岛的Tray=
(从池中的t开始)
其中t.TrayItems.Select(i=>i.roach)
.All(a=>selectedTrays
.SelectMany(s=>s.TrayItems)
.选择(i=>i.通道)
.载有(a))
选择t)
.ToList();
或者这个:
List<ITray> trayswithMatchingAisles = poolTrays
.Where(t => t.TrayItems
.Select(i => i.Aisle)
.All(a => selectedTrays
.SelectMany(s => s.TrayItems)
.Select(i => i.Aisle)
.Contains(a)))
.ToList();
List trayswithmatchingailes=poolTrays
.其中(t=>t.TrayItems
.选择(i=>i.通道)
.All(a=>selectedTrays
.SelectMany(s=>s.TrayItems)
.选择(i=>i.通道)
.包含(a)))
.ToList();
我认为您需要使用“SelectMany”扩展名,这是为了简化返回列表列表的查询
例如:
var distinctSelectedItems = selectedTrays.SelectMany(t => t.TrayItems).Select(ti => ti.Aisle).Distinct();
bool success = poolTrays.SelectMany(t => t.TrayItems).All(ti => distinctSelectedItems.Contains(ti.Aisle));
您还可以创建一个HashSet,以获得O(1)性能,而不是List.Contains的O(n)
var distinctSelectedItems = new HashSet<int>(selectedTrays.SelectMany(t => t.TrayItems).Select(ti => ti.Aisle));
bool success = poolTrays.SelectMany(t => t.TrayItems).All(ti => distinctSelectedItems.Contains(ti.Aisle));
var distinctSelectedItems=newhashset(selectedTrays.SelectMany(t=>t.TrayItems.Select(ti=>ti.roadle));
bool success=poolTrays.SelectMany(t=>t.TrayItems).All(ti=>distinctSelectedItems.Contains(ti.roach));
祝你好运。对不起,刚刚意识到a不是c。@jazza1000你能测试一下我的答案吗?它有用吗?(刚刚编辑)。+1是的,这是一个很好的方法。如果OP对
ITrayItem
的实现覆盖了Equals
方法,您的原始版本就可以工作了。是的,对不起,KK,这个版本工作得很好,以前的版本无法为我编译。@jazza1000以前的版本是在没有intellisense帮助的情况下手动键入的,我不得不说我还在练习LINQ
:)