联接不同对象的列表

本文关键字:列表 对象 | 更新日期: 2023-09-27 18:34:34

我有 2 个自定义类型列表。 他们有一个名为 ItemID 的公共元素,我想获取它们存在于一个元素中的所有元素,而不是另一个元素。 有人有什么想法吗?

我基本上需要与内部连接相反的方法,但只想要 itemList 中不在 itemCheckoutList 中的元素,或者如果 IsComplete 为真,它们可以在 itemCheckoutList 中。 这是我必须在 IsComplete 为假的情况下获得所有内部连接:

itemList.Join(itemCheckoutList,
         i => i.ItemID,
         ic => ic.ItemID,
         (i, ic) => new { itemList = i, itemCheckoutList = ic }).Where(x => x.itemCheckoutList.IsComplete == false).ToList();

联接不同对象的列表

我相信

这就是你想要的。

itemList.Where(i => i.IsComplete || 
                    !itemCheckoutList.Any(ic => ic.ItemID == i.ItemID))

编辑

根据您的评论,我认为这就是您想要的。

itemList.Where(i => !itemCheckoutList.Any(ic => ic.ItemID == i.ItemID && 
                                                !ic.IsComplete))

编辑

如果效率是一个问题,那么您将需要为itemCheckoutList创建一个可以重用的查找,或者只是按照 CodeCaster 的建议将itemCheckoutList更改为Dictionary<int, CheckOutItem>。 这是可以这样做的。

// This should preferably be called just once but 
// would need to be called whenever the list changes
var checkOutListLookup = itemCheckoutList.ToLookup(ic => ic.ItemID);
// and this can be called as needed.
var results = itemList.Where(i => !checkOutListLookup.Contains(i.ItemID) ||
                                  checkOutListLookup[i.ItemID].IsComplete);

或者如果你把它做成Dicionary<int, CheckOutItem>它看起来像这样。

var results = itemList.Where(i => !checkOutDictionary.ContainsKey(i.ItemID) ||
                                  checkOutDictionary[i.ItemID].IsComplete);

您也可以使用 GroupJoin

itemList
    .GroupJoin(itemCheckoutList, item => item.ItemID, itemCheckout => itemCheckout.ItemID, (item, itemCheckouts) => new {item, itemCheckouts})
    .SelectMany(t => t.itemCheckouts.DefaultIfEmpty(), (t, itemCheckout) => new { t.item, itemCheckout })
    .Where(t => t.item.IsComplete || t.itemCheckout == null)
    .Select(t => t.item);

或与 LINQ 查询相同的编写:

var l = from item in itemList
        join itemCheckout in itemCheckoutList on item.ItemID equals itemCheckout.ItemID into gj
        from itemCheckout in gj.DefaultIfEmpty()
        where item.IsComplete || itemCheckout == null
        select item;