У меня есть элементы List(Of DateTime). Как проверить, совпадают ли все элементы с помощью запроса LINQ? В любой момент времени в списке может быть 1, 2, 20, 50 или 100 элементов.
Спасибо
У меня есть элементы List(Of DateTime). Как проверить, совпадают ли все элементы с помощью запроса LINQ? В любой момент времени в списке может быть 1, 2, 20, 50 или 100 элементов.
Спасибо
Нравится:
if (list.Distinct().Skip(1).Any())
Or
if (list.Any(o => o != list[0]))
(что, вероятно, быстрее)
list.Distinct().Skip(1).Any()
ничем не отличается от list.Distinct().Count != 1
, верно?
- person Simon_Weaver; 17.09.2016
!(list.Any(o => o != list[0]))
, что верно, если нет элементов, отличающихся от первого, т.е. если они все одинаковые.
- person Simon_Weaver; 17.09.2016
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
Я создал простой метод расширения в основном для удобства чтения, который работает на любом 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;
}
Мой вариант:
var numUniques = 1;
var result = list.Distinct().Count() == numUniques;
Версия VB.NET:
If list.Distinct().Skip(1).Any() Then
Or
If list.Any(Function(d) d <> list(0)) Then
Это тоже вариант:
if (list.TrueForAll(i => i.Equals(list.FirstOrDefault())))
Он быстрее, чем if (list.Distinct().Skip(1).Any())
, и работает так же, как if (list.Any(o => o != list[0]))
, однако разница незначительна, поэтому я предлагаю использовать более читаемый.