如何检查一个列表是否包含另一个列表C#

时间:2018-07-07 08:47:12

标签: c# .net linq

我有两个域实体列表,

第一个是项目列表,结构:

string ItemID;
string ItemName;
int Qty;
double price;

另一个是商品清单,结构:

int OfferID;
string ItemID;
int OfferPrice;

具有两个这样的变量

List<DomainEntities.Items> ItemList=new List<DomainEntities.Items>();
List<DomainEntities.Offers> OfferList=new List<DomainEntities.Offers>();

现在我想从包含OfferList.ItemID的ItemList.ItemID属性进行过滤,输出应该是List。

该如何过滤? 谢谢!

2 个答案:

答案 0 :(得分:5)

您可以做到

ItemList.Where(item => OfferList.Any(offer => offer.ItemID == item.ItemID)).ToList();

您也可以执行此操作(执行速度可能更快)

ItemList.Join(OfferList, item => item.ItemID, offer => offer.ItemID, (item, offer) => item).ToList();

答案 1 :(得分:3)

如果列表变大(每个列表超过100个元素),则应研究一种更快的查找策略,例如HashSet<T>提供的查找策略。

List<DomainEntities.Items> itemList = new List<DomainEntities.Items>();
List<DomainEntities.Offers> offerList = new List<DomainEntities.Offers>();

var offerSet = new HashSet<string>(offerList.Select(o => o.ItemID));
var output = itemList.Where(item => offerSet.Contains(item.ItemID)).ToList();

HashSet<T>的优点在于,无论其大小如何,它都能提供恒定的查询性能。因此,如果itemList包含 m 个元素,而offerList包含 n 个元素,则上面的代码将大致需要 n 个操作来构建哈希集,但仅需一步就可以将任何项目与其进行比较。因此,总共需要 m 个步骤来针对它过滤itemList的所有元素。

相比之下,调用offerList.Any每次都需要遍历其元素,从而有效地导致了嵌套循环。因此,该方法将需要总共 m × n 个步骤,而不是 m + n 个步骤。对于大型集合而言,这变得很重要-如果两个列表每个都包含1,000个元素,则HashSet<T>方法将执行2,000步,而嵌套循环将执行1,000,000步。 (我在这里宽松地使用了“台阶”一词;实际上是指algorithmic complexity。)

Join运算符提供了与HashSet<T>相似的优化。