C# 使用其他列表的内容筛选列表
我有两张单子。我想使用第二个列表中的元素筛选出第一个列表。所以我有这个代码:C# 使用其他列表的内容筛选列表,c#,list,c#-4.0,filter,C#,List,C# 4.0,Filter,我有两张单子。我想使用第二个列表中的元素筛选出第一个列表。所以我有这个代码: List<data> dataList = somedata; IEnumerable<Filter> filterList = someFilterData; foreach (var s in filterList) { dataList = dataList .Where(l => l.dataId!= s.Id).ToList(); } 是否有人能
List<data> dataList = somedata;
IEnumerable<Filter> filterList = someFilterData;
foreach (var s in filterList)
{
dataList = dataList .Where(l => l.dataId!= s.Id).ToList();
}
是否有人能建议这是一个足够好的方法,或者我们如何使用其他技术使其更好。注意:列表可能会变大,因此我们也在考虑性能。可能您需要这个
dataList = dataList.Where(l => !filterList.Select(x => x.Id).Contains(l.dataId)).ToList();
我会这样做,使用hashset,然后使用一个
var filtIds = new HashSet<int>(filterList.Select(f=> f.Id));
var filteredDataList = dataList.Where(d=> !filtIds.Contains(d.dataId)).ToArray();
var-filterids=newhashset(filterList.Select(f=>f.Id));
var filteredDataList=dataList.Where(d=>!filteids.Contains(d.dataId)).ToArray();
您需要的是只获取筛选列表中找不到的项目。您可以采用“老式”方式,使用循环:
foreach (var listItem in dataList)
{
foreach (var filterItem in filterList)
{
if (listItem == filterItem)
{
dataList.Remove(listItem);
continue;
}
}
}
也可以使用LINQ进行过滤:
dataList.Where(d => filterList.All(f => f.Id != d.dataId))
晚会晚了,但是由于您的过滤器只知道是IEnumerable,所以对过滤器进行具体化以防止每次迭代时从源代码中吸取信息不是一个好主意吗?我想这就是乔治想要表达的意思。如果筛选器的源在执行过程中发生了更改,则可能会不一致(并且在每次迭代中重新获取它们可能会付出高昂的代价): 那么,“没有任何人”似乎(对我来说)比“所有人都不平等”更能说明你的意思
所以基本上你只想删除第一个列表中出现在第二个列表中的所有内容,性能很重要 我最喜欢,如果列表越来越大,它是最有效的。但是
List.RemoveAll
也更有效:
dataList.RemoveAll(d => filterList.Any(x => x.ID == d.DataID));
我会将过滤器Id放在一个hashset中,然后执行一个where,检查dataId是否不在hashfilterList中。filterList是筛选器列表,而不是ID或dataIds@AlwaysAProgrammer感谢您对错误的评论,我喜欢您的解决方案。它给出了正确的答案,而且是干净的。“我的解决方案给出了正确的答案,但似乎很笨拙。”莫格斯达感谢您提出这个问题。我阅读了你链接的StackExchange主题中的答案,我同意上面所说的。“我将在今天或明天详细说明我的答案。@Mogsdad…我不理解你的评论。”。被接受的答案也只是代码。我的解决方案不是“试试这个”解决方案。我实际上已经把它编码好了,而且它是有效的。@Mogsdad;谢谢你的解释。你说的很有道理。+1更有效的方法。但是他想过滤列表,因此
dataList=..ToList()
更合适。
var filterIds = filterList.Select( f=> f.Id ).ToArray( );
var results = dataList.Where( d=> !filterIds.Any( f=> d==f ) );
dataList.RemoveAll(d => filterList.Any(x => x.ID == d.DataID));