我需要比较两个相同类型的哈希集,但仅对某些属性具有不同的值。我基本上需要一个更具体的ExceptWith。
我试过使用ExceptWith,但据我所知,这不允许您指定要比较的属性。
我们应该假装我不能向 Person 类添加或删除任何属性。
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}");
}
}
}
最佳答案
您可以散列第二个数组中的名称以在 Linq 过滤器中使用以创建最终的 HashSet
var excludeName = new HashSet<string>(people2.Select(x => x.Name));
var hash3 = new HasSet<Person>(people1.Where(x => !exludeName.Contains(x.Name));
如果要排除的值列表非常大,这会特别有用,因为它会使整个过程在线性时间内运行。
或者这里是如何使用
HashSet
设置 IEqualityComparer<T>
。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();
}
}
注意:这意味着
HashSet
不能包含具有相同 Name
的两个项目,即使 Id
不同。但这也意味着它不能包含与当前设置具有相同值的不同对象。然后像这样使用它。
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)));
关于c# - 如何在一个属性上比较两个共享的 HashSet?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57314975/