ความแตกต่างระหว่าง each.with_index และ each_with_index ใน Ruby?


97

ฉันสับสนมากเกี่ยวกับความแตกต่างระหว่างและeach.with_index each_with_indexพวกเขามีประเภทที่แตกต่างกัน แต่ดูเหมือนจะเหมือนกันในทางปฏิบัติ


7
นอกเหนือจากความแตกต่างกันเล็กน้อยที่with_indexอนุญาตให้ดัชนีเริ่มต้นชดเชยwith_indexเป็นที่ต้องการโดยทั่วไปเมื่อใช้ร่วมกับmap, reduce, collectและอื่น ๆ ในระยะสั้นอ่านดีกว่าmap.with_index each_with_index.mapในแง่หนึ่งเมื่อใช้กับmapมันเป็นแบบสแตนด์อินสำหรับmap_with_indexวิธีการที่ไม่มีอยู่จริง
Cary Swoveland

คำตอบ:


175

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

42

each_with_indexได้รับการแนะนำให้รู้จักกับ Ruby ก่อนหน้านี้ with_indexได้รับการแนะนำในภายหลัง:

  1. เพื่อให้สามารถใช้งานได้กว้างขึ้นกับตัวแจงนับต่างๆ
  2. 0ที่จะช่วยให้ดัชนีเริ่มต้นจากจำนวนอื่นที่ไม่ใช่

วันนี้ใช้with_indexจะดีกว่าจากมุมมองของทั่วไปและการอ่าน แต่จากมุมมองของการเร่งขึ้นรหัสที่ทำงานได้เร็วขึ้นกว่าเล็กน้อยeach_with_indexeach.with_index

เมื่อคุณรู้สึกว่าวิธีการเดียวสามารถแสดงออกได้อย่างง่ายดายโดยการผูกมัดอย่างตรงไปตรงมาของวิธีการสองสามวิธีโดยปกติจะเป็นกรณีที่วิธีการเดียวนั้นเร็วกว่าโซ่ ในฐานะที่เป็นเช่นนี้อีกจะทำงานได้เร็วกว่าreverse_each reverse.eachวิธีการเหล่านี้มีเหตุผลอยู่


1
เพื่อความเป็นธรรมออฟเซ็ตไม่ได้เปลี่ยนดัชนี แต่เพียงแค่เพิ่มตัวเลขลงในดัชนี เมื่อคุณตรวจสอบดัชนีหลังการโทรคุณจะพบว่าดัชนีไม่ได้รับผลกระทบ บันทึกดีๆตามเคย @sawa
vgoff

2
ฉันไม่คิดว่า perf ควรจะแตกต่างกัน (อย่างน้อยก็ไม่มาก) ในreverseตัวอย่างreverseกำลังส่งคืนอาร์เรย์อื่นไม่ใช่ตัวแจงนับ หากส่งคืนตัวแจงนับก็ไม่ควรช้าลงด้วยการใช้งานที่ดี
akostadinov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.