Я рассматриваю разницу между этими методами в рубине. Я знаю, что select
возвращает массив элементов, а detect
возвращает только один и первый согласованный элемент. Но есть ли разница, если я наберу array.select{ condition }[0]
? Он вернет первую единицу, например detect
. Например:
a = [2,3,4,5]
a.detect{|k| k.even? }
# => 2
a.select{|k| k.even? }[0]
# => 2
Кто-нибудь может объяснить мне другие различия между этими методами и привести несколько примеров, когда {{X 0}} будет лучше, чем select
?
3 ответа
Когда вам нужно получить только один элемент, предпочтительнее использовать detect
, потому что он прекратит итерацию по массиву, когда найдет первое вхождение, соответствующее условию. Поскольку select
извлекает все вхождения, которые соответствуют условию, он должен перебирать весь список. В худшем случае (когда элемент, соответствующий условию, отсутствует в списке), они эквивалентны, но если элемент, который вы ищете, находится в начале списка, detect
будет более эффективным.
Разница в том, что detect
вернет первое значение, которое блок оценивает как истинное, в данном случае это число 2
. Это быстрее, если вам нужно только одно значение из массива, потому что он не будет оценивать остальную часть массива после нахождения одного значения, которое возвращает true
.
select
вернет каждый элемент, который возвращает true
в зависимости от блока, поэтому он вернет [2,4]
. select
будет оценивать блок для каждого элемента, поэтому он медленнее, чем detect
.
Основываясь на том, что вы сделали в своем примере, где вы выбираете только первый элемент, который вернул select
, лучше использовать вместо него detect
.
Хорошей иллюстрацией этого будет, скажем, у вас есть массив из 10 миллионов элементов, в которых случайные числа от 0 до 1 миллиона.
arr = Array.new(1_000_000) { rand(1_000_000) }
Если вы просто хотите вернуть первое четное число, использование detect
в этом значении будет значительно быстрее, чем select
. Вот контрольные измерения для detect
и select
.
detect: 0.000000 0.000000 0.000000 ( 0.000010)
select: 0.740000 0.010000 0.750000 ( 0.753949)
Я бы разместил здесь пример, который ИМХО все проясняет:
(1..Float::INFINITY).detect &:odd?
#⇒ 1
(1..Float::INFINITY).select(&:odd?).first
#⇒ :(
Похожие вопросы
Новые вопросы
arrays
Массив - это упорядоченная линейная структура данных, состоящая из набора элементов (значений, переменных или ссылок), каждый из которых идентифицируется одним или несколькими индексами. Когда вы спрашиваете о конкретных вариантах массивов, используйте вместо них следующие связанные теги: [vector], [arraylist], [matrix]. При использовании этого тега в вопросе, относящемся к языку программирования, пометьте вопрос используемым языком программирования.