2011-08-13 41 views
1

我發現這篇文章Match elements between 2 collections with Linq in c#,它解釋瞭如何使用Intersect來找到兩個列表之間的匹配元素。使用Linq與子值相交?

您可以使用它來匹配兩個不完全相同的列表中的元素,但是要匹配的是「子值」?

我的例子是這樣的:我有兩個集合,每個集合都包含XElements列表。一個元素名爲<link>,另一個元素名爲<file>,每個元素都有稱爲「路徑」的屬性,它是我想匹配的屬性。如果路徑屬性相同,我想要一個匹配。

在結果集中,我想列出所有元素的路徑與元素路徑相匹配的元素。

這怎麼辦?

+0

所以「路徑」是屬性而不是對象的屬性?順便說一下,你知道LambdaComparer嗎? – sll

+0

[與兩個不同對象相交的列表]的可能重複(http://stackoverflow.com/questions/11285045/intersect-two-lists-with-different-objects) –

回答

2

我建議使用LambdaComparer可以傳遞到Intersect()方法的相等比較器,它允許通過提供布爾條件每次代替引入一個新的比較器類來代替指定的比較邏輯,因此您的代碼將被很清楚:

firstCollection.Intersect(
       secondCollection, 
       new LambdaComparer<YourClass>(
        (item1, item2) => item1.PropertyName == item2.PropertyName)); 


// Below are lists and User class which demonstrates LambdaComparer and Intersect() 
public class User 
{ 
     public string Name { get; set; } 
} 

IList<User> list1 = new List<User> 
     { 
      new User {Name = "A"}, 
      new User { Name = "B"} 
     }; 
List<User> list2 = new List<User> 
     { 
      new User {Name = "C"}, 
      new User { Name = "B"} 
     }; 

var resultSet = list1.Intersect<User>(
     list2, 
     new LambdaComparer<User>((item1, item2) => item1.Name == item2.Name)); 

基本上,如果你需要比較cusotm屬性,也可以封裝這種邏輯到

Func<User, User, bool> userNameComparer = (user1, user2) => 
{ 
// check attributes using user1.GetType().GetCustomAttributes() 
}; 

然後使用該比較器功能可按爲:

var resultSet = list1.Intersect<User>(
        list2, 
        new LambdaComparer<User>((item1, item2) => userNameComparer)); 

編輯:注意ragarding在這個回答中引用特定impelemntaion 有可能是因爲默認情況下,散列功能可按被硬編碼的問題0

6 public LambdaComparer(Func<T, T, bool> lambdaComparer) : 
7    this(lambdaComparer, o => 0) 
8   { 
9   } 

這可能導致性能問題在一些所以我建議將它重構爲:

public LambdaComparer(Func<T, T, bool> lambdaComparer) : 
       this(lambdaComparer, 
         EqualityComparer<T>.Default.GetHashCode(o)) 
      { 
      } 

因此,它將使用內置的GetHashCode()執行

+0

+1用於指出'LambdaComparerr'。看起來很有用。 –

+0

謝謝,好的提示! – Anders

+0

@安德斯·斯文森:參見編輯部分,歡呼! – sll