2015-08-14 77 views
3

我有两个列表。我想用第二个列表中的一个元素过滤掉第一个列表。所以我有这样的代码:使用另一个列表的内容过滤列表

List<data> dataList = somedata; 
IEnumerable<Filter> filterList = someFilterData; 

,然后我用这个代码过滤:

foreach (var s in filterList) 
{ 
    dataList = dataList .Where(l => l.dataId!= s.Id).ToList();  
} 

可有人请建议,如果这是一个足够好的方法或者我们如何能更好地使用一些让其他技术。注意:该列表可能会变大,因此我们也在考虑性能。

+0

我把过滤器ID的HashSet的内部,然后做一个单一的地方,检查是否数据ID是不是哈希里面 – George

回答

3

你需要的是仅取这些物品不能在被发现过滤器列表。你能做到这一点,在“老派”的方式,使用循环:

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)) 
+1

我喜欢你的解决方案。它给出了正确的答案,并且是干净的。我的解决方案给出了正确的答案,但似乎笨重。 – AlwaysAProgrammer

+1

@Mogsdad感谢提出这个问题。我从StackExchange的主题中阅读了你链接的答案,并且同意在那里说的东西。我会在今天或明天回答我的问题。 – Kapol

0

也许,你需要这个

dataList = dataList.Where(l => !filterList.Select(x => x.Id).Contains(l.dataId)).ToList(); 
+0

filterList.Contains这里是一个错误。 filterList是一个过滤器列表,而不是一个ID或数据ID列表 – AlwaysAProgrammer

+0

@AlwaysAProgrammer感谢您对错误的评论 –

1

我会做到这一点,使用HashSet的再一个如果:

var filtIds = new HashSet<int>(filterList.Select(f=> f.Id)); 
var filteredDataList = dataList.Where(d=> !filtIds.Contains(d.dataId)).ToArray(); 
+0

+1更有效的方法。但他想过滤列表,所以'dataList = .... ToList()'更合适。 –

0
var filteredQuery = 
       from d in dataList 
       let filterListIds = from f in filterList 
        select f.Id 
       where filterListIds.Contains(d.DataId) == false 
       select d; 
+2

@Mogsdad ...我不明白你的意见。接受的答案也仅限于代码。我的解决方案不是一个'尝试这个'解决方案。我实际上编码它,它的工作原理。 – AlwaysAProgrammer

+0

@Mogsdad;感谢您的解释。你所说的确实很有道理。 – AlwaysAProgrammer

1

迟到了,但因为你的过滤器只知道IEnumerable,为了防止在每次迭代中从源头吮吸,可能不是一个好主意吗?我认为这是@乔治正在接受的。如果过滤器的源改变中期执行,也可能是不一致的(以及可能的成本来重新获取它们在每次迭代):

var filterIds = filterList.Select(f=> f.Id).ToArray(); 

那么,“没有什么”似乎只是(对我)说你的意思比“所有不等于”更重要。

var results = dataList.Where(d=> !filterIds.Any(f=> d==f)); 
0

所以基本上你只是想从第一个列表中删除所有出现在第二个列表中并且性能很重要?

我最喜欢Georges approach,如果名单越来越大,它是最有效的。但List.RemoveAll也更高效:

dataList.RemoveAll(d => filterList.Any(x => x.ID == d.DataID));