C# 根据包含ID的列表选择项目

C# 根据包含ID的列表选择项目,c#,linq,C#,Linq,我有一个项目列表,每个项目都包含一个整型字段 我想筛选我的列表,只获取与给定整数列表匹配的项 我现在的代码可以工作,但我知道它可以优化 Class Item { int ID; //Other fields & methods that are irrelevant here } //Selection method IEnumerable<Item> SelectItems(List<Item> allItems, List<int&g

我有一个项目列表,每个项目都包含一个整型字段

我想筛选我的列表,只获取与给定整数列表匹配的项

我现在的代码可以工作,但我知道它可以优化

Class Item
{
    int ID;

    //Other fields & methods that are irrelevant here
}

//Selection method
IEnumerable<Item> SelectItems(List<Item> allItems, List<int> toSelect)
{
     return allItems.Where(x => toSelect.Contains(x.ID));
}
我的问题是,我迭代了Allitem,在每次迭代中,我迭代了toSelect

我觉得这可能会更有效,但我不知道我怎样才能用Linq做到这一点

这可能也是一个已经被问过的问题,因为我不知道这在英语中是怎么称呼的。这感觉有点愚蠢,因为我不知道如何在搜索引擎中正确地表达这一点。

您可以使用Join,它更有效,因为它使用的是基于集合的方法:

var selectedItems = from item in allItems
                    join id in toSelect
                    on item.Id equals id
                    select item;
return selectedItems;
另一种更有效的方法是使用哈希集而不是列表:

IEnumerable<Item> SelectItems(List<Item> allItems, HashSet<int> toSelect)
{
     return allItems.Where(x => toSelect.Contains(x.ID));
}
您可以使用Join,因为它使用的是基于集合的方法,因此效率更高:

var selectedItems = from item in allItems
                    join id in toSelect
                    on item.Id equals id
                    select item;
return selectedItems;
另一种更有效的方法是使用哈希集而不是列表:

IEnumerable<Item> SelectItems(List<Item> allItems, HashSet<int> toSelect)
{
     return allItems.Where(x => toSelect.Contains(x.ID));
}

有两种方法可以做到这一点

目前,您有ON×M性能,其中N是allitem的大小,M是toSelect的大小

如果您只是想简单地减少它,那么您可以通过创建toSelect的散列集将其减少到ON+OM:


无需预先进行哈希选择,因为我们不检查它是否包含内容。有两种方法可以实现这一点

目前,您有ON×M性能,其中N是allitem的大小,M是toSelect的大小

如果您只是想简单地减少它,那么您可以通过创建toSelect的散列集将其减少到ON+OM:


无需预先进行哈希选择,因为在使用LINQ to对象时,我们不会检查它是否包含

,它是通过查找内部第二个操作数来实现的。这意味着它将在Allitem上建立一个查找,这将非常昂贵,而且比字典更昂贵,因为它需要处理我们可能没有预料到的多样性。我的观点是:在使用LINQtoObjects时要小心:这并不像你想象的那么明显。您可以在核心clr源中的参考源中看到这一点:@MarcGravell:所以在toSelect中使用allItems join id中的from项是一个优化…?我希望这会执行得更好,是的;无论哪种方式,它都会对所有项进行扫描,但至少它只会构建一个较小集合的查找,我们可以合理地假设它是toSelect@MarcGravell:好的,请相应地编辑我的答案,谢谢您的提醒。使用LINQ to对象时,它是通过查找内部第二个操作数实现的。这意味着它将在Allitem上建立一个查找,这将非常昂贵,而且比字典更昂贵,因为它需要处理我们可能没有预料到的多样性。我的观点是:在使用LINQtoObjects时要小心:这并不像你想象的那么明显。您可以在核心clr源中的参考源中看到这一点:@MarcGravell:所以在toSelect中使用allItems join id中的from项是一个优化…?我希望这会执行得更好,是的;无论哪种方式,它都会对所有项进行扫描,但至少它只会构建一个较小集合的查找,我们可以合理地假设它是toSelect@MarcGravell:好的,编辑了我的答案,谢谢提醒。