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
,如果是,如何?
我觉得这很优雅:
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>
。
您可以重写MyObject
的Equals
和GetHashCode
,以提供在您的情况下相等的含义,或者实现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();
}