3

我有以下对象:

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 中的每个元素,我想比较选定托盘列表中的过道。如果所有过道都匹配,我想将其添加到要返回的托盘列表中。我只是有点纠结,试图让 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 个实例

4

3 回答 3

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()));
于 2013-08-05T02:23:10.527 回答
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();
于 2013-08-05T02:23:46.533 回答
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));

祝你好运。

于 2013-08-05T02:35:56.103 回答