разница между each.with_index и each_with_index в Ruby?

94

Я действительно смущен разницей между each.with_indexи each_with_index. Они имеют разные типы, но на практике кажутся идентичными.

Стэн
источник
7
Помимо небольшой разницей , что with_indexпозволяет начальный индекс смещения, with_indexкак правило , предпочтительно при использовании в сочетании с map, reduce, collectи т.д. Короче говоря, map.with_indexчитает лучше each_with_index.map. В некотором смысле, при использовании с map, он заменяет несуществующий map_with_indexметод.
Cary Swoveland

Ответы:

173

with_indexМетод принимает необязательный параметр , чтобы компенсировать начальный индекс. each_with_indexделает то же самое, но не имеет необязательного начального индекса.

Например:

[:foo, :bar, :baz].each.with_index(2) do |value, index|
    puts "#{index}: #{value}"
end

[:foo, :bar, :baz].each_with_index do |value, index|
    puts "#{index}: #{value}"
end

Выходы:

2: foo
3: bar
4: baz

0: foo
1: bar
2: baz
черная волна
источник
41

each_with_indexбыл введен в Ruby ранее. with_indexбыл представлен позже:

  1. для более широкого использования с различными перечислителями.
  2. чтобы индекс мог начинаться с числа, отличного от 0.

Сегодня использование with_indexбыло бы лучше с точки зрения общности и удобочитаемости, но с точки зрения ускорения кода each_with_indexработает немного быстрее, чем each.with_index.

Когда вы чувствуете, что один метод может быть легко выражен путем прямого объединения нескольких методов, обычно бывает так, что один метод быстрее, чем цепочка. Что касается другого примера этого, reverse_eachработает быстрее, чем reverse.each. У этих методов есть основания для существования.

сава
источник
1
Честно говоря, смещение не меняет индекс, оно просто добавляет к нему число. Когда вы проверите индекс после звонка, вы обнаружите, что он не изменился. Хорошие заметки, как обычно, @sawa
vgoff
2
Я не думаю, что производительность должна отличаться (по крайней мере, не существенно). В этом reverseпримере reverseвозвращается другой массив, а не перечислитель. Если он вернул перечислитель, то при хорошей реализации он не должен был быть медленнее.
akostadinov