diferença entre each.with_index e each_with_index em Ruby?

93

Estou muito confuso sobre a diferença entre each.with_indexe each_with_index. Eles têm tipos diferentes, mas parecem ser idênticos na prática.

Stan
fonte
6
Além da diferença ligeira que with_indexpermite um deslocamento índice inicial, with_indexé geralmente preferível quando utilizado em conjunto com map, reduce, collect, etc Em suma, map.with_indexlê melhor do que each_with_index.map. Em certo sentido, quando usado com map, é um substituto para o map_with_indexmétodo inexistente .
Cary Swoveland

Respostas:

170

O with_indexmétodo usa um parâmetro opcional para compensar o índice inicial. each_with_indexfaz a mesma coisa, mas não tem índice inicial opcional.

Por exemplo:

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

Saídas:

2: foo
3: bar
4: baz

0: foo
1: bar
2: baz
maré negra
fonte
41

each_with_indexfoi introduzido no Ruby anteriormente. with_indexfoi introduzido mais tarde:

  1. para permitir um uso mais amplo com vários enumeradores.
  2. para permitir que o índice comece a partir de um número diferente de 0.

Hoje, usar with_indexseria melhor do ponto de vista da generalidade e legibilidade, mas do ponto de vista de agilizar o código, each_with_indexroda um pouco mais rápido do que each.with_index.

Quando você sente que um único método pode ser facilmente expresso pelo encadeamento direto de alguns métodos, geralmente o método único é mais rápido do que a cadeia. Quanto a outro exemplo disso, reverse_eaché executado mais rápido do que reverse.each. Esses métodos têm razão de existir.

sawa
fonte
1
Para ser justo, porém, o deslocamento não altera o índice, ele simplesmente adiciona um número ao índice. Ao verificar o índice após a sua chamada, você descobrirá que ele não foi afetado. Boas notas, como de costume, @sawa
vgoff
2
Não acho que o desempenho deva ser diferente (pelo menos não substancialmente). No reverseexemplo, o reverseestá retornando outra matriz e não um enumerador. Se ele retornou um enumerador, então não deveria ter sido mais lento com uma boa implementação.
akostadinov