Подтвердить что ты не робот

Интервью Вопрос:.Any() vs if (.Length> 0) для тестирования, если коллекция имеет элементы

В недавнем интервью меня спросили, какая разница между .Any() и .Length > 0 и почему я буду использовать либо при тестировании, чтобы увидеть, есть ли в коллекции элементы.

Это немного меня бросило, поскольку кажется немного очевидным, но я чувствую, что, возможно, что-то не хватает.

Я предложил использовать .Length, когда вам просто нужно знать, что коллекция имеет элементы и .Any(), когда вы хотите отфильтровать результаты.

Предположительно .Any() также принимает удар производительности, поскольку он должен выполнять цикл/запрос внутри.

4b9b3361

Ответ 1

Length существует только для некоторых типов коллекций, таких как Array.

Any - это метод расширения, который можно использовать с любой коллекцией, реализующей IEnumerable<T>.

Если присутствует Length, вы можете использовать его, в противном случае используйте Any.


Предположительно. Любой() принимает удар производительности, так как он должен выполнять цикл/запрос внутри.

Enumerable.Any не работает. Он извлекает итератор и проверяет, возвращается ли MoveNext true. Вот исходный код .NET Reflector.

public static bool Any<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        if (enumerator.MoveNext())
        {
            return true;
        }
    }
    return false;
}

Ответ 2

Я предполагаю, что интервьюер, возможно, хотел спросить о проверке Any() против Count() > 0 (в отличие от Length > 0).

В принципе, здесь сделка.

Any() будет эффективно пытаться определить, имеет ли коллекция какие-либо элементы путем перечисления по одному элементу. (Существует перегрузка для проверки данного критерия с помощью Func<T, bool>, но я предполагаю, что интервьюер имел в виду версию Any(), которая не принимает аргументов.) Это делает ее O (1).

Count() будет проверять свойство Length или Count (от T[] или ICollection или ICollection<T>). Обычно это будет O (1). Однако, если это не доступно, он будет считать элементы в коллекции, перечислив все это. Это будет O (n).

A Count или Length свойство, если доступно, скорее всего будет O (1) точно так же, как Any(), и, вероятно, будет работать лучше, поскольку это не потребует перечислить вообще. Но метод расширения Count() не гарантирует этого. Поэтому иногда это O (1), иногда O (n).

Предположительно, если вы имеете дело с неопределенным IEnumerable<T>, и вы не знаете, реализует ли он ICollection<T> или нет, вам гораздо лучше использовать Any(), чем Count() > 0, если ваше намерение просто убедиться, что коллекция не пуста.

Ответ 3

Length - свойство типов массивов, а Any() - метод расширения Enumerable. Поэтому вы можете использовать длину только при работе с массивами. При работе с более абстрактными типами (IEnumerable<T>) вы можете использовать Any().

Ответ 4

.Length... System.Array .Any... IEnumerable (метод расширения).

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

Хотя реализация "Any" не будет делать ничего, кроме приведенного ниже кода.

 private static bool Any<T>(this IEnumerable<T> items)
        {
            return items!=null && items.GetEnumerator().MoveNext();
        }

Кроме того, Лучшим вопросом может быть разница между ".Count" и ".Length", что говорят:).

Ответ 5

Я думаю, что это более общий вопрос о том, что выбрать, если у нас есть 2 способа выразить что-то. В ситуации я бы предложил утверждение: "Будь конкретным" цитата от Питера Норвига в его книге PAIP

Быть конкретным средним использованием, что лучше всего описывает то, что вы делаете. Таким образом, вы хотите сказать что-то вроде:

collection.isEmpty()

Если у вас нет такой конструкции, я выберу общую идиому, которую использовали сообщества. Для меня .Length > 0 не самый лучший, поскольку он налагает на то, что вы можете определить размер объекта. Предположим, что ваш инструмент имеет бесконечный список. .Lenght, очевидно, не будет работать.

Ответ 6

Звучит очень похоже на этот вопрос Stackoverflow о различии между .Count и .Any для проверки существования результата: Проверить наличие результата в Linq-to-xml

В этом случае лучше использовать Any, а затем Count, поскольку Count будет перебирать все элементы IEnumerable

Ответ 7

Мы знаем, что .Length используется только для массивов, а .Any() используется для коллекций IEnumerable.

Вы можете поменять местами. Установить для .Length, и у вас есть тот же вопрос для работы с коллекциями IEnumberable

Оба .Any() и .Count выполняют нулевую проверку перед началом перечислителя. Поэтому в отношении производительности они одинаковы.

Что касается массива, предположим, что мы имеем следующую строку:

int[] foo = new int[10];

Здесь foo.Length равно 10. Хотя это правильно, это может быть не ваш ответ, потому что мы еще ничего не добавили в массив. Если foo имеет значение null, он выдает исключение.

Ответ 8

.Length выполняет итерацию через коллекцию и возвращает количество элементов. Сложность O(n)

.Any проверяет, имеет ли коллекция хотя бы один элемент. Сложность O(1).