2015-08-14 81 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));