我有以下对象:
public interface ITray
{
int OrderNo {get; set;}
IEnumerable<ITrayItem> TrayItems {get;}
}
public interface ITrayItem
{
int Aisle {get; set;}
}
现在,我有两个List对象,
List<ITray> selectedTrays
List<ITray> poolTrays
我想要做的是对于poolTrays中的每个元素,我想比较所选托盘列表中的Aisles。如果过道的全部匹配,我想将其添加到要返回的托盘列表中。 我只是想让自己陷入困境,试图让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();
所以,如果我选择了托盘A,B,C,括号中有过道 A [1,2,3] B [4,5,6] c [7,8,9]
然后在过道[7,9]中使用TrayItems的poolTray应该成功返回,但是不应该在列表中返回带有TrayItems [7,8,9,10]的池托盘。
目前,我在poolTray列表中传入(仅)[7,9],并在我的Linq查询中返回了2个实例
答案 0 :(得分:2)
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()));
答案 1 :(得分:2)
这样的事情应该有效:
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();
但这可以简化为:
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();
或者这个:
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();
答案 2 :(得分:2)
我认为您需要使用“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));
祝你好运。