2013-11-21 26 views
0

我試圖根據其中一個屬性與另一個列表的屬性匹配來過濾列表。 在下面的例子中,只有兩個列表中具有共同'名稱'的項目才能在第一個列表中過濾。有人能告訴我最簡潔的做法嗎?如何根據C#中兩個列表中的常見項目獲取過濾列表#

class TCapability 
{ 
    public string Name { get; set; } 
    public int Id { get; set; } 
} 

class PCapability 
{ 
    public string Name { get; set; } 
    public int Code { get; set; } 
} 

輸入:

var capability = new List<TCapability>() 
{ 
    new TCapability() {Name="a", Id=1}, 
    new TCapability() {Name="b", Id=2}, 
    new TCapability() {Name="c", Id=3} 
}; 

var type2Capability = new List<PCapability>() 
{ 
    new PCapability() {Name="a", Code=100}, 
    new PCapability() {Name="b", Code=200}, 
    new PCapability() {Name="d", Code=300} 
}; 

預期輸出:

capability = 
{ 
    { Name="a", Id=1 }, 
    { Name="b", Id=2 } 
} 
+0

您的預期輸出必須是什麼類型? 'TCapability','PCapability',還是帶字符串的東西? – AgentFire

+1

你試過了嗎?任何錯誤? –

+1

你應該讓任何人都可以輕鬆地嘗試你的代碼。出於這個原因我編輯了你的代碼。 –

回答

2
var result = capability.Where(c => type2Capability.Any(c2 => c.Name == c2.Name)); 
+2

我會首先將'type2Capability'變成'HashSet ',這樣查找就是'O(1)',否則這就是'O(mn)',但這是一個很大的當你實際上不需要聯合結果時,更簡單的替代方法是「加入」。 – Rawling

+1

@Rawling同意! –

+0

@ MD.Unicorn它沒有過濾結果。我還是得到了與Capability最初一樣的結果數量。 –

1

你可以嘗試使用join clause這樣

capability = (from a in capability 
      join b in type2Capability on a.Name equals b.Name 
      select a).ToList(); 

UPDATE的評論,如果type2Capability可以有重名

capability = (from a in capability 
      join b in type2Capability on a.Name equals b.Name into f 
      where f.Any() 
      select a).ToList(); 
+0

在'type2Capability'具有重複的Name屬性的情況下,這會產生多重結果 - 我會使用'GroupJoin'(在查詢語法中加入...),然後丟棄其中的項目該組是空的。 – Rawling

+1

@Rawling更新這個案件的答案 – Grundy

1

如果列表可以長期做下去,然後一個HashSet可以加快速度。

var set = new HashSet<string>(type2Capability.Select(t => t.Name)); 
var res = capability.Where(c => set.Contains(c.Name)); 
相關問題