MyObject 列表中的每个 属性-Value 必须是唯一的

Each Property-Value in a MyObject-list must be unique

假设我有以下对象:

public class MyObject
{
    public string MyValue { get; set; }
}

在另一个 class 中,我有这些对象的列表:

public class MyClass
{
    private List<MyObject> _list;

    public MyClass(List<MyObject> myObjects)
    {
        _list = myObjects;
    }

    public bool AllUniqueValues()
    {
        ...
    }
}

我想检查列表中的所有 MyObjects 是否都具有唯一(非重复)Value。当我使用以下内容时它有效:

public bool AllUnique()
{
    return _list.All(x => _list.Count(y => String.Equals(y.Value, x.Value)) == 1);
}

但我觉得这可以做得更容易/更优雅。所以,我的问题是,是否有更好/更优雅的方法来检查所有 MyObjects 是否具有非重复的 Value,如果是,如何?

解决这个问题最优雅的方法是使用 set 数据结构。独特元素的无序集合。在 .NET 中,您需要使用 HashSet<T>

您可以覆盖 MyObjectEqualsGetHashCode 以提供在您的情况下相等的含义,或者实施 IEqualityComparer<T>.

如果您实例化 HashSet<T> 而您没有提供 IEqualityComparer<T> 实现,那么它将使用您的覆盖,否则它将使用整个实现。通常,如果同一对象的 equality 含义不止 ,则您会实施相等比较器。

我可能仍然需要有序的元素集合

如果您仍然需要按顺序存储对象,则可以同时将元素存储在 HashSet<T>List<T> 中。当您需要检查项目是否存在、获取项目或在集合中执行某些支持的操作时,使用 HashSet<T> 获得的实际上是对项目的 O(1) 访问权限,因为它是散列集合,它不会不需要完全迭代它来找到元素。

我觉得这很优雅:

public static class EnumerableExtensions
{
    public static bool AllUnique<TSource, TResult>(this IEnumerable<TSource> enumerable, 
        Func<TSource, TResult> selector)
    {
        var uniques = new HashSet<TResult>();
        return enumerable.All(item => uniques.Add(selector(item)));
    }
}

现在您的代码变为:

 var allUnique = _list.AllUnique(i => i.MyValue);

其中一种方法:

return !_list.GroupBy(c=>c.MyValue).Any(c=>c.Count() > 1);

至少清晰了一点

有很多方法可以做到这一点,但就我个人而言,我会这样做:

public bool AllUnique()
{
    return _list.GroupBy(x => x.MyValue).Count() == _list.Count();
}