Убедитесь, что все элементы IEnumerable <T?> Имеют одинаковое значение с помощью LINQ - PullRequest
9 голосов
/ 04 декабря 2010

У меня есть обнуляемый тип, например SomeEnum? и набор значений, например, IEnumerable<SomeEnum?>.

Как проверить, что все элементы имеют одинаковое значение с помощью LINQ (и получить это значение)?

Ответы [ 4 ]

16 голосов
/ 18 марта 2011
data.Distinct().Count() == 1;

тоже хорошо работает.

9 голосов
/ 04 декабря 2010
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));
}
5 голосов
/ 04 декабря 2010
var value = data.Distinct().Single();

(который выдает исключение, если не существует только одного уникального значения, в противном случае он возвращает это значение)

Если вы не хотите исключений:

var few=data.Distinct().Take(2).ToList();
if(few.Count==1) {
    var value = few[0];
    ...
}
3 голосов
/ 02 октября 2015

Ленивый и возвращает 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;
    }
}
...