我需要比较两个相同类型的哈希集,但仅对某些属性具有不同的值。我基本上需要一个更具体的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/

10-13 03:19