2014-01-08 3 views

ответ

14

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] 
+1

Проверьте документацию, к которой вы привязались - оба имеют одинаковые описания и оба возвращают массивы для данного блока. –

+0

@ DylanMarkow Я не согласен, вы его перепроверяете. –

+2

Я думаю, вы должны привести пример, показывающий, что в целом 'select' и' find_all' не ведут себя одинаково. – toro2k

7

Да, для массивов, они возвращают одинаковые результаты. Для других вещей (например, хэши) они могут возвращать разные вещи.

В соответствии с документацией Enumerable для select и find_all оба метода указывают на один и тот же исходный код, и оба возвращают либо массив (если задан блок), либо Enumerator (если блок не указан).

В то время как класс Array реализует свою собственную версию select (но позволяет перечислимую ручку find_all), они все равно делают то же самое.

+0

-1 за сказанное * Да, они возвращают идентичные результаты * Это не так. –

+0

Для своего примера, массив, они возвращают одинаковые результаты. Код, используемый для его получения, может быть немного другим, но нет случая, когда, учитывая тот же массив, два метода не возвратят то же самое. –

+0

OP спросил * Идет ли find_all и выбирает то же самое в рубине? * .. OP, вероятно, взял Array в качестве примера. Но OP спросил его в целом. –

51

#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]] 
Смежные вопросы