sự khác biệt giữa each.with_index và each_with_index trong Ruby?


93

Tôi thực sự bối rối về sự khác biệt giữa each.with_indexeach_with_index. Chúng có nhiều loại khác nhau nhưng dường như giống hệt nhau trong thực tế.


6
Bên cạnh những khác biệt nhỏ mà with_indexcho phép một chỉ số bắt đầu bù đắp, with_indexthường được ưa thích khi sử dụng kết hợp với map, reduce, collectvv Nói tóm lại, map.with_indexđọc tốt hơn so với each_with_index.map. Theo một nghĩa nào đó, khi được sử dụng với map, nó là một giá trị thay thế cho map_with_indexphương thức không tồn tại .
Cary Swoveland

Câu trả lời:


170

Các with_indexphương pháp lấy một tham số tùy chọn để bù đắp các chỉ số bắt đầu. each_with_indexlàm điều tương tự, nhưng không có chỉ mục bắt đầu tùy chọn.

Ví dụ:

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

Kết quả đầu ra:

2: foo
3: bar
4: baz

0: foo
1: bar
2: baz

41

each_with_indexđã được đưa vào Ruby trước đó. with_indexđã được giới thiệu sau:

  1. để cho phép sử dụng rộng rãi hơn với các điều tra viên khác nhau.
  2. để cho phép chỉ mục bắt đầu từ một số khác 0.

Ngày nay, việc sử dụng with_indexsẽ tốt hơn từ quan điểm tổng quát và dễ đọc, nhưng từ quan điểm tăng tốc mã, each_with_indexchạy nhanh hơn một chút each.with_index.

Khi bạn cảm thấy rằng một phương pháp duy nhất có thể dễ dàng được thể hiện bằng cách xâu chuỗi đơn giản một vài phương thức, thì thường là phương pháp đơn nhanh hơn chuỗi. Đối với một ví dụ khác về điều này, reverse_eachchạy nhanh hơn reverse.each. Những phương pháp này có lý do để tồn tại.


1
Công bằng mà nói, phần bù không thay đổi chỉ số, nó chỉ thêm một số vào chỉ mục. Khi bạn kiểm tra chỉ mục sau cuộc gọi của mình, bạn sẽ thấy nó không bị ảnh hưởng. Ghi chú tốt như thường lệ, @sawa
vgoff

2
Tôi không nghĩ perf nên khác (ít nhất là không đáng kể). Trong reverseví dụ, hàm reversetrả về một mảng khác, không phải là một liệt kê. Nếu nó trả về một điều tra viên, thì nó không nên chậm hơn với việc triển khai tốt.
akostadinov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.