我需要比较两个相同类型的标签,但仅对于某些属性就有不同的值。我本质上需要一个更具体的除外。
我已经尝试使用Excestwith,但据我所知,这不允许您指定属性进行比较。
我们应该假装我不能将任何属性添加或删除任何属性。
class Program
{
private class Person
{
public string Name { get; set; }
public string Id { get; set; }
}
static void Main(string[] args)
{
var people1 = new[]
{
new Person
{
Name = "Amos",
Id = "123"
},
new Person
{
Name = "Brian",
Id = "234"
},
new Person
{
Name = "Chris",
Id = "345"
},
new Person
{
Name = "Dan",
Id = "456"
}
};
var people2 = new[]
{
new Person
{
Name = "Amos",
Id = "098"
},
new Person
{
Name = "Dan",
Id = "987"
}
};
var hash1 = new HashSet<Person>(people1);
var hash2 = new HashSet<Person>(people2);
var hash3 = new HashSet<Person>(); // where hash3 is hash1 without the objects from hash2 solely based on matching names, not caring about Id matching
foreach (var item in hash3) // should print out Brian, Chris
{
Console.WriteLine($"{item.Name}");
}
}
}
在您的Person
类中,您应该定义自己的GetHashCode
方法,以便它仅使用该人的名称而不是ID。
如果这样做,您还必须定义自己的 Equals
方法:为什么覆盖等于equals方法时覆盖gethashcode很重要?
您可以将第二个数组中的名称放在linq滤波器中以创建最终的HashSet
var excludeName = new HashSet<string>(people2.Select(x => x.Name));
var hash3 = new HasSet<Person>(people1.Where(x => !exludeName.Contains(x.Name));
,如果要排除的值列表非常大,这将特别有用,因为它将整个过程以线性时间运行。
或这是您可以使用IEqualityComparer<T>
设置HashSet
s的方法。
public class PersonByNameComparer : IEqualityComparer<Peron>
{
public bool Equals(Person p1, Persion p2)
{
return p1.Name == p2.Name;
}
public int GetHashCode(Person p)
{
return p.Name.GetHashCode();
}
}
注意:这意味着即使Id
不同,HashSet
S也不能包含两个具有相同Name
的项目。但这也意味着它不能包含具有与当前设置相同值的不同对象。
然后这样使用。
var comparer = new PersonByNameComparer();
var hash1 = new HashSet<Person>(people1, comparer);
var hash2 = new HashSet<Person>(people2, comparer);
// Note that ExceptWith will mutate the existing hash.
hash1.ExceptWith(hash2);
// Alternatively you can create the new hash like this
var hash3 = new HashSet<Persion>(hash1.Where(p => !hash2.Contains(p)));
您可以使用linq:
进行此操作var hash3 = hash1.Where(x=>!hash2.Select(y=>y.Name).Contains(x.Name)).ToHashSet();
这仅创建了Hash2的名称的集合,然后从Hash1中获取所有名称不在该集合中的人。