Проверьте, все ли элементы одинаковы в списке

У меня есть элементы List(Of DateTime). Как проверить, совпадают ли все элементы с помощью запроса LINQ? В любой момент времени в списке может быть 1, 2, 20, 50 или 100 элементов.

Спасибо


person Saif Khan    schedule 15.03.2011    source источник


Ответы (5)


Нравится:

if (list.Distinct().Skip(1).Any())

Or

if (list.Any(o => o != list[0]))

(что, вероятно, быстрее)

person SLaks    schedule 15.03.2011
comment
Потенциально легче читать с All вместо Any. Вы также можете использовать First() вместо [0] в случае невозможности доступа к списку (IEnumerable). если (список.Все(о =› о == список.Первый())) { ... } - person Graeme Wicksted; 09.09.2014
comment
list.Distinct().Skip(1).Any() ничем не отличается от list.Distinct().Count != 1, верно? - person Simon_Weaver; 17.09.2016
comment
@GraemeWicksted весь смысл Any() в том, чтобы быть быстрее, если найден один элемент, который НЕ соответствует. Тогда вы перестанете оценивать список. Что ЯВЛЯЕТСЯ немного яснее, так это !(list.Any(o => o != list[0])), что верно, если нет элементов, отличающихся от первого, т.е. если они все одинаковые. - person Simon_Weaver; 17.09.2016
comment
@Simon_Weaver Any() используется для поиска хотя бы 1 совпадения, а All() используется для обеспечения совпадения всех элементов. В любом случае, если обнаруживается несовпадение в All или совпадение в Any, итерация будет остановлена. Таким образом, !(list.Any(o => o != list[0])); и list.All(o => o == list[0]); всегда будут иметь одинаковое количество итераций. Таким образом, оба будут иметь примерно одинаковое время выполнения. P.S. Вы правы, в том, что list.Distinct().Skip(1).Any() аналогичен list.Distinct().Count != 1, просто имейте в виду, что Count может быть медленнее, чем Any (возможно, даже в этом случае) с › 1 элементом. - person Graeme Wicksted; 19.09.2016
comment
Но count должен перебирать весь отдельный список. Если у вас более 2 наборов, это медленнее. - person Lee Louviere; 16.09.2019

Я создал простой метод расширения в основном для удобства чтения, который работает на любом IEnumerable.

if (items.AreAllSame()) ...

И реализация метода:

    /// <summary>
    ///   Checks whether all items in the enumerable are same (Uses <see cref="object.Equals(object)" /> to check for equality)
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="enumerable">The enumerable.</param>
    /// <returns>
    ///   Returns true if there is 0 or 1 item in the enumerable or if all items in the enumerable are same (equal to
    ///   each other) otherwise false.
    /// </returns>
    public static bool AreAllSame<T>(this IEnumerable<T> enumerable)
    {
        if (enumerable == null) throw new ArgumentNullException(nameof(enumerable));

        using (var enumerator = enumerable.GetEnumerator())
        {
            var toCompare = default(T);
            if (enumerator.MoveNext())
            {
                toCompare = enumerator.Current;
            }

            while (enumerator.MoveNext())
            {
                if (toCompare != null && !toCompare.Equals(enumerator.Current))
                {
                    return false;
                }
            }
        }

        return true;
    }
person MSkuta    schedule 07.03.2016
comment
Хороший! Просто интересно узнать о реализации пустого списка. Я не уверен, могу ли я предположить, что пустой список означает, что все одинаковы - это похоже на случай, когда потребитель должен справиться, поэтому я думаю, что я собираюсь выбросить, если список пуст. Яблоки одинаковые? Без понятия, потому что в корзине нет яблок - person Dirk Boer; 18.10.2019

Мой вариант:

var numUniques = 1;
var result = list.Distinct().Count() == numUniques;
person VBorisoff    schedule 05.05.2019
comment
Мне это нравится, это очень читабельно и показывает намерение по сравнению с решением skip1/any. - person tkit; 29.11.2019

Версия VB.NET:

If list.Distinct().Skip(1).Any() Then

Or

If list.Any(Function(d) d <> list(0)) Then
person jor    schedule 24.07.2013

Это тоже вариант:

 if (list.TrueForAll(i => i.Equals(list.FirstOrDefault())))

Он быстрее, чем if (list.Distinct().Skip(1).Any()), и работает так же, как if (list.Any(o => o != list[0])), однако разница незначительна, поэтому я предлагаю использовать более читаемый.

person KungFury    schedule 24.11.2017