Эти два утверждения дают мне те же результаты:Является ли «find_all» и «выбирает» то же самое?
[1,2,3,4].find_all { |x| x.even? }
[1,2,3,4].select{ |x| x.even? }
Is find_all
просто псевдоним? Есть ли причина использовать один над другим?
Эти два утверждения дают мне те же результаты:Является ли «find_all» и «выбирает» то же самое?
[1,2,3,4].find_all { |x| x.even? }
[1,2,3,4].select{ |x| x.even? }
Is find_all
просто псевдоним? Есть ли причина использовать один над другим?
Enumerable#find_all
Возвращает массив, содержащий все элементы перечисления, для которых данный блок возвращает истинное значение, которое не относится к select
. Enumerable#select
возвращает Array
, если приемник, на который вы звоните, #select
, не имеет собственного #select
метода. В противном случае, на каком приемнике вы вызываете метод #select
, он будет возвращать аналогичный тип приемника после обработки состояния блока.
Как Hash#select
Возвращает новый хэш, состоящий из записей, для которых блок возвращается true
и Array#select
возвращает новый массив, содержащий все элементы Ары, для которых данный блок возвращает истинное значение. Теперь Range#select
вернет вам Array
, так как класс Range
не имеет собственного метода экземпляра, который называется #select
. Вместо того, чтобы быть Enumerable
, он назовет Enumerable#select
.
rng = (1..4)
ary = [1,2]
hsh = {:a => 1}
rng.method(:select) # => #<Method: Range(Enumerable)#select>
hsh.method(:select) # => #<Method: Hash#select>
ary.method(:select) # => #<Method: Array#select>
Вот полный демонстрация с примером в-пользу моего объяснения выше:
hsh = {:a => 2, :b => 3 }
ary = [1,2,3]
rng = (1..3)
# Look find_all always gives Array.
hsh.find_all{ true } # => [[:a, 2], [:b, 3]]
ary.find_all{ true } # => [1, 2, 3]
rng.find_all{ true } # => [1, 2, 3]
# Look select not giving Array always, explanation of why so is written
# above in my answer.
hsh.select{ true } # => {:a=>2, :b=>3}
ary.select{ true } # => [1, 2, 3]
rng.select{ true } # => [1, 2, 3]
Проверьте документацию, к которой вы привязались - оба имеют одинаковые описания и оба возвращают массивы для данного блока. –
@ DylanMarkow Я не согласен, вы его перепроверяете. –
Я думаю, вы должны привести пример, показывающий, что в целом 'select' и' find_all' не ведут себя одинаково. – toro2k
Да, для массивов, они возвращают одинаковые результаты. Для других вещей (например, хэши) они могут возвращать разные вещи.
В соответствии с документацией Enumerable для select и find_all оба метода указывают на один и тот же исходный код, и оба возвращают либо массив (если задан блок), либо Enumerator (если блок не указан).
В то время как класс Array реализует свою собственную версию select
(но позволяет перечислимую ручку find_all
), они все равно делают то же самое.
-1 за сказанное * Да, они возвращают идентичные результаты * Это не так. –
Для своего примера, массив, они возвращают одинаковые результаты. Код, используемый для его получения, может быть немного другим, но нет случая, когда, учитывая тот же массив, два метода не возвратят то же самое. –
OP спросил * Идет ли find_all и выбирает то же самое в рубине? * .. OP, вероятно, взял Array в качестве примера. Но OP спросил его в целом. –
#find_all
и #select
очень похожи; разница очень тонкая. В большинстве случаев они эквивалентны. Это зависит от класса, реализующего его.
Enumerable#find_all
и Enumerable#select
работают по тому же коду.
То же самое происходит для Array
и Range
, так как они используют Enumerable
.
В случае Hash
, #select
переопределяется для возврата хэша вместо массива, но #find_all
наследуется от Enumerable
a = [1, 2, 3, 4, 5, 6]
h = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}
a.select{|x| x.even?} # => [2, 4, 6]
a.find_all{|x| x.even?} # => [2, 4, 6]
h.select{|k,v| v.even?} # => {:b=>2, :d=>4, :f=>6}
h.find_all{|k,v| v.even?} # => [[:b, 2], [:d, 4], [:f, 6]]
Этот вопрос принят неправильный ответ. – henrebotha