加入不同对象的列表

mgr*_*ier 1 c# linq lambda

我有2个自定义类型列表.它们有一个名为ItemID的公共元素,我希望得到它们存在于一个元素中的所有元素,而不是另一个元素.有没有人有任何想法?

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

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

juh*_*arr 5

我相信这就是你想要的.

itemList.Where(i => i.IsComplete || 
                    !itemCheckoutList.Any(ic => ic.ItemID == i.ItemID))
Run Code Online (Sandbox Code Playgroud)

编辑

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

itemList.Where(i => !itemCheckoutList.Any(ic => ic.ItemID == i.ItemID && 
                                                !ic.IsComplete))
Run Code Online (Sandbox Code Playgroud)

编辑

如果效率是一个问题,那么你要创建一个查询itemCheckoutList,你可以重复使用或者只是改变itemCheckoutListDictionary<int, CheckOutItem>如CodeCaster建议.这可以这样做.

// 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);
Run Code Online (Sandbox Code Playgroud)

或者,如果你做了Dicionary<int, CheckOutItem>它,它会是这样的.

var results = itemList.Where(i => !checkOutDictionary.ContainsKey(i.ItemID) ||
                                  checkOutDictionary[i.ItemID].IsComplete);
Run Code Online (Sandbox Code Playgroud)

  • 如果这是一个问题,OP可以为`itemCheckoutList`创建`Dictionary <ItemID,Item>`来执行`.ContainsKey()`on,这是'O(1)`. (2认同)