diferencia entre each.with_index y each_with_index en Ruby?

94

Estoy realmente confundido acerca de la diferencia entre each.with_indexy each_with_index. Tienen diferentes tipos pero parecen ser idénticos en la práctica.

Stan
fuente
6
Aparte de la ligera diferencia de que with_indexpermite un índice de desplazamiento inicial, with_indexse prefiere en general cuando se utiliza en conjunción con map, reduce, collect, etc. En resumen, map.with_indexlee mejor que each_with_index.map. En cierto sentido, cuando se usa con map, es un sustituto del map_with_indexmétodo inexistente .
Cary Swoveland

Respuestas:

172

El with_indexmétodo toma un parámetro opcional para compensar el índice inicial. each_with_indexhace lo mismo, pero no tiene un índice de inicio opcional.

Por ejemplo:

[: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

Salidas:

2: foo
3: bar
4: baz

0: foo
1: bar
2: baz
marea negro
fuente
41

each_with_indexse introdujo en Ruby anteriormente. with_indexfue introducido más tarde:

  1. para permitir un uso más amplio con varios enumeradores.
  2. para permitir que el índice comience desde un número distinto de 0.

Hoy en día, usar with_indexsería mejor desde el punto de vista de generalidad y legibilidad, pero desde el punto de vista de acelerar el código, se each_with_indexejecuta un poco más rápido que each.with_index.

Cuando cree que un método único se puede expresar fácilmente mediante el encadenamiento directo de unos pocos métodos, suele ocurrir que el método único es más rápido que la cadena. En cuanto a otro ejemplo de esto, reverse_eachcorre más rápido que reverse.each. Estos métodos tienen razón de existir.

sawa
fuente
1
Sin embargo, para ser justos, el desplazamiento no cambia el índice, simplemente agrega un número al índice. Cuando revise el índice después de su llamada, encontrará que no se ve afectado. Buenas notas como siempre, @sawa
vgoff
2
No creo que el rendimiento deba ser diferente (al menos no sustancialmente). En el reverseejemplo, reversedevuelve otra matriz y no un enumerador. Si devolvió un enumerador, entonces no debería haber sido más lento con una buena implementación.
akostadinov