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>
。
您可以覆盖 MyObject
的 Equals
和 GetHashCode
以提供在您的情况下相等的含义,或者实施 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();
}
假设我有以下对象:
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>
。
您可以覆盖 MyObject
的 Equals
和 GetHashCode
以提供在您的情况下相等的含义,或者实施 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();
}