різниця між each.with_index та each_with_index у Ruby?


94

Мене дуже бентежить різниця між each.with_indexі each_with_index. Вони мають різні типи, але на практиці здаються однаковими.


6
Крім невеликою різницею , що with_indexдозволяє початковий індекс зсуву, with_indexяк правило , переважно при використанні в поєднанні з map, reduce, collectі т.д. Коротше кажучи, map.with_indexчитає краще each_with_index.map. У певному сенсі, коли він використовується з map, це вставка для неіснуючого map_with_indexметоду.
Кері Своуленд

Відповіді:


171

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
Я не думаю, що perf повинен відрізнятися (принаймні не суттєво). У цьому reverseприкладі reverseфункція повертає інший масив, а не перечислювач. Якщо він повернув перечислювач, тоді це не повинно було бути повільнішим при хорошій реалізації.
Акостадінов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.