我发现这篇文章Match elements between 2 collections with Linq in c#解释了如何使用Intersect查找两个列表之间的匹配元素。
您是否可以使用它来匹配两个不完全相同但具有您想要匹配的“子值”的列表中的元素?
我的例子是这样的:我有两个集合,每个集合都包含XElements列表。一个名为<link>
的元素和另一个名为<file>
的元素,每个元素都有一个名为“path”的属性,这是我想要匹配的属性。如果path属性相等,我想要一个匹配。
在结果集中,我想要一个路径与元素路径匹配的所有元素的列表。
如何做到这一点?
答案 0 :(得分:2)
我建议使用可以作为Equality Comparer传递给Intersect()
方法的LambdaComparer,它允许通过提供布尔条件来指定比较逻辑,而不是每次都引入一个新的比较器类,所以你的代码足够清晰:
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));
编辑:请注意本回答中引用的特定问题
可能存在一个问题,默认情况下哈希函数是硬编码的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()
实现