myobject列表中的每个属性值必须是唯一的

本文关键字:唯一 列表 myobject 属性 | 更新日期: 2023-09-27 18:14:31

假设我有以下对象:

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

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

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,如果是,如何?

myobject列表中的每个属性值必须是唯一的

我觉得这很优雅:

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);

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

您可以重写MyObjectEqualsGetHashCode,以提供在您的情况下相等的含义,或者实现IEqualityComparer<T>

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

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

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

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

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