我有List<Organisation>
个组织。
每个Organisation
都有一个属性List<int> Categories
。
我还有一个单独的List<int> DisplayCategories
我想创建一个名为List<Organisation>
的新DisplayOrganisations
。
DisplayOrganisations
将Organisation
Categories
中出现List<int> DisplayCategories
个{/ 1}}。
如何使用linq或lambda实现此目的?
以下内容不正确:
DisplayOrganisations = (from o in Organisations
where o.Categories.Intersect(DisplayCategories.CategoryIds)
select o).ToList();
我收到错误:
无法隐式转换类型 'System.Collections.Generic.IEnumerable'到'bool'
我认为这是因为我选择了需要将类别子列表与单独的列表DisplayCategories进行比较的组织。
有什么想法吗?
答案 0 :(得分:3)
确定相交不会给出布尔值。您可能想要检查其中是否存在任何元素使用Any
。
DisplayOrganisations = Organisations
.Where(o => o.Categories.Intersect(DisplayCategories.CategoryIds)
.Any()).ToList();
或更好的方法。
DisplayOrganisations = Organisations.Where(o =&gt; o.Categories
.ANY(xDisplayCategories.CategoryIds.Contains))ToList();
正如您在图像中看到的,Intersect使用的hashset比第二种方法更快,因为Hashset的时间复杂度为O(1)
,用于添加和删除项目。所以一般来说,Intersect是O(n+m)
。但使用Any
和Contains
的第二种方法的时间复杂度为O(n^2)
,这可能会变慢。感谢Dmitry Dovgopoly。
答案 1 :(得分:2)
如果您只需要所有元素都在CategoryIds
列表中的组织,则可以混合使用Except()
和Any()
方法:
var DisplayOrganisations = Organisations.Where(o =>
!o.Categories.Except(DisplayCategories.CategoryIds).Any()).ToList();
如果您只想检查ID列表中至少有一个ID,可以使用.Any
方法:
var DisplayOrganisations = Organisations.Where(o => o.Categories
.Any(DisplayCategories.CategoryIds.Contains)).ToList();