【发布时间】:2010-12-04 17:48:47
【问题描述】:
我有一个可以为空的类型,例如SomeEnum? 和一组值,例如IEnumerable<SomeEnum?>.
如何使用 LINQ 检查所有项目是否具有相同的值(并获取该值)?
【问题讨论】:
标签: c# linq .net-3.5 ienumerable
我有一个可以为空的类型,例如SomeEnum? 和一组值,例如IEnumerable<SomeEnum?>.
如何使用 LINQ 检查所有项目是否具有相同的值(并获取该值)?
【问题讨论】:
标签: c# linq .net-3.5 ienumerable
data.Distinct().Count() == 1;
效果也很好。
【讨论】:
public static bool AllEqual<T>(this IEnumerable<T?> values) where T : struct
{
if (!values.Any()) return true;
T? first = values.First();
return values.Skip(1).All(v => first.Equals(v));
}
编辑:要获取值,您可以返回一个元组(成功,值),如下所示:
public Tuple<bool, T?> AllEqual<T>(IEnumerable<T?> values) where T : struct
{
if(! values.Any()) return Tuple.Create(true, (T?)null);
T? first = values.First();
bool equal = values.Skip(1).All(v => v.Equals(first));
return Tuple.Create(equal, equal ? first : (T?)null);
}
或者您可以使用 out 参数:
public static bool AllEqual<T>(this IEnumerable<T?> values, out T? value) where T : struct
{
value = null;
if (!values.Any()) return true;
T? first = values.First();
value = first;
return values.Skip(1).All(v => first.Equals(v));
}
【讨论】:
!values.Any() - 此实现假定空序列中的所有项目都是空的并且“值”为空。您可能想要抛出异常。 values.All(...) 返回序列中的每个项目是否满足某些条件 - 在这种情况下,每个其他项目是否等于第一个(因此都相等)。
懒惰并为空序列返回 true:
public static bool AllEqual<T>(this IEnumerable<T> source, out T value)
{
using (var enumerator = source.GetEnumerator())
{
if (!enumerator.MoveNext())
{
value = default(T);
return true;
}
value = enumerator.Current;
var comparer = EqualityComparer<T>.Default;
while (enumerator.MoveNext())
{
if (!comparer.Equals(value, enumerator.Current))
{
return false;
}
}
return true;
}
}
【讨论】:
var value = data.Distinct().Single();
(如果不存在唯一的唯一值,则会抛出异常,否则将返回该值)
如果你不想要异常:
var few=data.Distinct().Take(2).ToList();
if(few.Count==1) {
var value = few[0];
...
}
【讨论】:
Take(2) 如果Distinct() 返回 1-length 集合会抛出异常,不是吗?