Unterschied zwischen each.with_index und each_with_index in Ruby?

93

Ich bin wirklich verwirrt über den Unterschied zwischen each.with_indexund each_with_index. Sie haben unterschiedliche Typen, scheinen aber in der Praxis identisch zu sein.

Stan
quelle
6
Abgesehen von der geringen Differenz , die with_indexeinen Startindex ermöglicht Offset, with_indexwird im allgemeinen bevorzugt , wenn in Verbindung mit map, reduce, collectusw. Kurz gesagt, map.with_indexliest besser als each_with_index.map. In gewisser Weise ist es bei Verwendung mit mapein Ersatz für die nicht existierende map_with_indexMethode.
Cary Swoveland

Antworten:

170

Die with_indexMethode verwendet einen optionalen Parameter, um den Startindex zu versetzen. each_with_indexmacht das gleiche, hat aber keinen optionalen Startindex.

Beispielsweise:

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

Ausgänge:

2: foo
3: bar
4: baz

0: foo
1: bar
2: baz
schwarze Flut
quelle
41

each_with_indexwurde früher in Ruby eingeführt. with_indexwurde später eingeführt:

  1. um eine breitere Verwendung mit verschiedenen Enumeratoren zu ermöglichen.
  2. Damit der Index von einer anderen Zahl als beginnen kann 0.

Heutzutage with_indexwäre die Verwendung unter dem Gesichtspunkt der Allgemeinheit und Lesbarkeit besser, aber unter dem Gesichtspunkt der Beschleunigung des Codes each_with_indexläuft sie etwas schneller als each.with_index.

Wenn Sie der Meinung sind, dass eine einzelne Methode leicht durch einfaches Verketten einiger weniger Methoden ausgedrückt werden kann, ist die einzelne Methode normalerweise schneller als die Kette. Wie für ein anderes Beispiel, reverse_eachläuft schneller als reverse.each. Diese Methoden haben Grund zu existieren.

sawa
quelle
1
Um fair zu sein, ändert der Offset den Index nicht, sondern fügt dem Index einfach eine Zahl hinzu. Wenn Sie den Index nach Ihrem Anruf überprüfen, werden Sie feststellen, dass er nicht betroffen ist. Gute Notizen wie immer, @sawa
vgoff
2
Ich denke nicht, dass Perf anders sein sollte (zumindest nicht wesentlich). In diesem reverseBeispiel gibt das ein reverseanderes Array und keinen Enumerator zurück. Wenn es einen Enumerator zurückgegeben hat, sollte es mit einer guten Implementierung nicht langsamer sein.
Akostadinov