Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查IEnumerable的所有项目<;T?>;使用LINQ具有相同的值_C#_Linq_.net 3.5_Ienumerable - Fatal编程技术网

C# 检查IEnumerable的所有项目<;T?>;使用LINQ具有相同的值

C# 检查IEnumerable的所有项目<;T?>;使用LINQ具有相同的值,c#,linq,.net-3.5,ienumerable,C#,Linq,.net 3.5,Ienumerable,我有一个可空类型,例如SomeEnum?和一组值,例如IEnumerable 如何使用LINQ检查所有项目是否具有相同的值(并获取该值) (如果不存在唯一值,则将引发异常,否则将返回该值) 如果不希望出现异常: var few=data.Distinct().Take(2).ToList(); if(few.Count==1) { var value = few[0]; ... } 公共静态bool AllEqual(此IEnumerable值),其中T:struct { 如果

我有一个可空类型,例如
SomeEnum?
和一组值,例如
IEnumerable

如何使用LINQ检查所有项目是否具有相同的值(并获取该值)

(如果不存在唯一值,则将引发异常,否则将返回该值)

如果不希望出现异常:

var few=data.Distinct().Take(2).ToList();
if(few.Count==1) {
    var value = few[0];
    ...
}
公共静态bool AllEqual(此IEnumerable值),其中T:struct
{
如果(!values.Any())返回true;
T?first=值。first();
返回值.Skip(1).All(v=>first.Equals(v));
}
编辑:要获取值,可以返回如下元组(success,value):

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);
}
公共元组AllEqual(IEnumerable值),其中T:struct
{
if(!values.Any())返回Tuple.Create(true,(T?)null);
T?first=值。first();
bool equal=values.Skip(1).All(v=>v.Equals(first));
返回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));
}
public static bool AllEqual(这是IEnumerable value,out T?value),其中T:struct
{
值=空;
如果(!values.Any())返回true;
T?first=值。first();
值=第一;
返回值.Skip(1).All(v=>first.Equals(v));
}

也可以很好地工作。

懒惰,对于空序列返回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;
    }
}
public static bool AllEqual(此IEnumerable源,out T值)
{
使用(var enumerator=source.GetEnumerator())
{
如果(!enumerator.MoveNext())
{
值=默认值(T);
返回true;
}
值=枚举数。当前值;
var comparer=EqualityComparer.Default;
while(枚举数.MoveNext())
{
如果(!comparer.Equals(value,enumerator.Current))
{
返回false;
}
}
返回true;
}
}

Take(2)
如果
Distinct()
返回长度为1的集合,将引发异常,不是吗?@abatishchev:不,不会。它是在“尽力而为”的基础上工作的。@abatishchev Take(n)是Take最多,而不是Takeexactly@abatishchev-还要注意,这些是序列,而不是集合(直到ToList)。一个微妙的区别,也许-直到您获得高容量…这对于LINQ to对象更可取,因为它会在发现一个不相等的值时立即退出。在LINQ中,它会导致3次往返。@stripling-这个问题的所有答案都会短路。EF无论如何都会将其视为L2O,因为它不使用Queryable,除非接口是IQueryable@Marc格雷威尔:说得好。我不知道Distinct是否是可靠的。应该假设它是。@stripling-值得注意的是,因为并非所有序列都是可重复的,即使在L2O中,也应该避免多次重复reads@abatishchev-假设你的意思是
!values.Any()
检查空序列-此实现假定空序列中的所有项都为空,并且“value”为null。您可能希望抛出一个异常
values.All(…)
返回序列中的每个项是否满足某些条件-在本例中,每个其他项是否等于第一项(因此都相等)。好主意。并且可以使用与Lee's way+1相同的扩展方法进行包装,以避免像Distinct这样的中间列表和像first answer这样的多次迭代,这是一些序列不支持的。绝对是这个列表中最好的实现。我同意Mike的观点-非常好的解决方案。但并没有像问题的作者所问的那个样使用LINQ。
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));
}
data.Distinct().Count() == 1;
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;
    }
}