我有两个通用列表,我想运行几个Linq查询来查找:
列表B中的任何列表A项目
列表B中的所有列表A项目
以下是清单:
var ListA = new List<long>()
var ListB = new List<MyObject>()
MyObject定义为:
public class MyObject
{
public long ItemId { get; set; }
// ... Other stuff...
}
我正在尝试确定两件事(两个查询):1。ListA中的任何长整数是否与ListB中的任何MyObject.ItemId匹配? 2. ListA中的所有多头都可以在ListB中找到吗?
ListA和ListB的长度可以不同。对于2号,我需要在ListB中找到所有ListA的项目,但反之亦然。我希望这是有道理的。
谢谢,
-Scott
答案 0 :(得分:6)
首先,你只关心ListB中的ItemIds,所以:
var bIDs = ListB.Select(x => x.ItemId);
要回答问题的第一部分,我会通过找到两个列表的交集(它们共享的所有项目的集合)来解决这个问题。如果它中至少有一个元素,则两者之间存在重叠。
var sharedIds = ListA.Intersect(bIDs);
if (sharedIds.Any())
// list A contains at least one ItemID which ListB contains
至于第二部分,你想看看列表A是否是列表B的子集。搜索这个,Stack Overflow呈现clean solution:
if (!ListA.Except(bIDs).Any())
// yes, list A is a subset of list B
此代码段有效,因为ListA.Except(bIDs)
找到了ListA
所拥有的bIDs
没有的元素。如果这是空的,则ListA
不包含bIDs
没有的任何内容。因此,ListA
中的所有内容也位于bIDs
。
以下是一个例子:A = {1, 2}
; B = {1, 2, 3}
。 A是B的一个子集。A.Except(B)
给你一个空集 - B有1和2,所以不能在结果列表中,并且B中没有任何东西。所以当A是a时B的子集,A.Except(B).Any()
给出错误,因为结果中没有元素;所以如果我们想处理那个案子,我们显然会否定它。
为了完整性,如果我们交换A和B轮,使得A不是B的一个子集:A = {1, 2, 3}
; B = {1, 2}
,然后A.Except(B)
提供{3}
。它不能包含1或2,因为B包含1和2.但是B不包含3,因此A.Except(B)
可以包含它。由于{3}
包含一个元素,因此它不为空,因此A.Except(B).Any()
为真。否定,如果A不是B的子集,则为假。
我的解释有点简洁;如果你想进一步研究(我建议你这样做 - 一点设定理论可以走很长的路),A.Except(B)
是LINQ的集合差异或相对集合补充的名称。如果你这么倾向的话,Wikibooks有一套很好的introduction来设定理论。
答案 1 :(得分:1)
var value1 =
(
from itemA in ListA
where ListB.Any(itemB => itemB.ItemID == itemA)
select item
).Count();
var value2 = value1 == ListA.Count();
答案 2 :(得分:0)
要测试条件,假设您将ItemIds
列表提取到listB
:
bool inListA = listA.Any(x => listB.Contains(x));
bool allInListB = listA.All(x => listB.Contains(x));
如果ItemIds
bool inListA = listA.Any(x => listB.Select(b => b.ItemId).Contains(x));
bool allInListB = listA.All(x => listB.Select(b => b.ItemId).Contains(x));
答案 3 :(得分:0)
如果您需要同时回答所有三个问题,那么纯LINQ解决方案很可能不是最优的,因为每个查询都需要执行相同的交叉操作。交叉一次,然后使用该结果回答你的三个问题:
var tempSet = new HashSet<long>(ListA);
int uniqueAItemCount = tempSet.Count;
// 2b. "I would need all of ListA's items found in ListB, but not vice-versa."
tempSet.IntersectWith(ListB.Select(x => x.ItemId));
// tempSet now contains all items from ListA also found in ListB
// we can use this result to answer the other two questions...
// 1. "Do any of the longs in ListA match any of the MyObject.ItemId in ListB?"
bool anyAFoundInB = tempSet.Count > 0;
// 2a. "Can all of the longs in ListA be found in ListB?"
bool allAFoundInB = tempSet.Count == uniqueAItemCount;