ฉันไม่ได้บอกว่าArray
-> |value,index|
และHash
-> |key,value|
ไม่ได้บ้า (ดูความคิดเห็นของ Horace Loeb) แต่ฉันกำลังพูดว่ามีวิธีที่มีเหตุผลที่จะคาดหวังข้อตกลงนี้
เมื่อฉันจัดการกับอาร์เรย์ฉันมุ่งเน้นไปที่องค์ประกอบในอาร์เรย์ (ไม่ใช่ดัชนีเพราะดัชนีนั้นชั่วคราว) ใช้วิธีการแต่ละคนมีดัชนีเช่นดัชนี + แต่ละหรือ | แต่ละดัชนี | |value,index|
หรือ สิ่งนี้สอดคล้องกับดัชนีที่ถูกมองว่าเป็นอาร์กิวเมนต์ที่เป็นทางเลือกเช่น | value | เทียบเท่ากับ | value, index = nil | ซึ่งสอดคล้องกับ | ค่าดัชนี |
เมื่อฉันจัดการกับ hashes ผมมากขึ้นมักจะมุ่งเน้นไปที่ปุ่มกว่าค่าและฉันกำลังมักจะจัดการกับคีย์และค่าในลำดับที่ทั้งหรือkey => value
hash[key] = value
หากคุณต้องการการพิมพ์แบบเป็ดให้ใช้วิธีการที่กำหนดไว้อย่างชัดเจนเช่น Brent Longborough ที่แสดงหรือวิธีการทางอ้อมตามที่ maxhawkins แสดง
Ruby เป็นเรื่องเกี่ยวกับการรองรับภาษาให้เหมาะกับโปรแกรมเมอร์ไม่ใช่เกี่ยวกับโปรแกรมเมอร์ที่เหมาะสมกับภาษา นี่คือเหตุผลที่มีหลายวิธี มีหลายวิธีที่จะคิดเกี่ยวกับบางสิ่ง ใน Ruby คุณเลือกที่ใกล้เคียงที่สุดและส่วนที่เหลือของรหัสมักจะตกต่ำและรัดกุมมาก
สำหรับคำถามดั้งเดิม "อะไรคือ" วิธีที่ถูกต้อง "ในการวนซ้ำผ่านอาร์เรย์ใน Ruby?" ดีฉันคิดว่าวิธีที่สำคัญ (เช่นไม่มีพลัง syntactic น้ำตาลหรืออำนาจเชิงวัตถุ) คือ:
for index in 0 ... array.size
puts "array[#{index}] = #{array[index].inspect}"
end
แต่รูบีนั้นเกี่ยวกับน้ำตาล syntactic ที่ทรงพลังและพลังเชิงวัตถุ แต่อย่างไรก็ตามนี่คือสิ่งที่เทียบเท่ากับแฮชและสามารถสั่งซื้อกุญแจได้หรือไม่:
for key in hash.keys.sort
puts "hash[#{key.inspect}] = #{hash[key].inspect}"
end
ดังนั้นคำตอบของฉันคือ "วิธี" ที่ถูกต้อง "ในการวนซ้ำในอาร์เรย์ใน Ruby ขึ้นอยู่กับคุณ (เช่นโปรแกรมเมอร์หรือทีมเขียนโปรแกรม) และโครงการ" โปรแกรมเมอร์ที่ดีกว่าของ Ruby นั้นเป็นตัวเลือกที่ดีกว่า โปรแกรมเมอร์ Ruby ที่ดีกว่ายังคงมองหาวิธีการเพิ่มเติม
ตอนนี้ฉันต้องการถามคำถามอื่นว่า "อะไรคือ" วิธีที่ถูก "ในการทำซ้ำใน Range ใน Ruby backward?"! (คำถามนี้เป็นวิธีที่ฉันมาที่หน้านี้)
มันเป็นการดีที่จะทำ (สำหรับการส่งต่อ):
(1..10).each{|i| puts "i=#{i}" }
แต่ฉันไม่ชอบทำ (ย้อนหลัง):
(1..10).to_a.reverse.each{|i| puts "i=#{i}" }
จริง ๆ แล้วฉันไม่ได้สนใจที่จะทำสิ่งนั้นมากเกินไป แต่เมื่อฉันสอนไปข้างหลังฉันต้องการแสดงให้นักเรียนเห็นว่ามีความสมมาตรที่ดี (เช่นมีความแตกต่างน้อยที่สุดเช่นเพียงเพิ่มสิ่งที่ตรงกันข้ามหรือขั้นตอน -1 แต่ไม่มี แก้ไขสิ่งอื่นใด) คุณสามารถทำได้ (เพื่อความสมมาตร):
(a=*1..10).each{|i| puts "i=#{i}" }
และ
(a=*1..10).reverse.each{|i| puts "i=#{i}" }
ซึ่งฉันไม่ชอบมาก แต่คุณไม่สามารถทำ
(*1..10).each{|i| puts "i=#{i}" }
(*1..10).reverse.each{|i| puts "i=#{i}" }
#
(1..10).step(1){|i| puts "i=#{i}" }
(1..10).step(-1){|i| puts "i=#{i}" }
#
(1..10).each{|i| puts "i=#{i}" }
(10..1).each{|i| puts "i=#{i}" } # I don't want this though. It's dangerous
ในที่สุดคุณสามารถทำได้
class Range
def each_reverse(&block)
self.to_a.reverse.each(&block)
end
end
แต่ฉันต้องการสอนทับทิมบริสุทธิ์แทนที่จะเป็นวิธีการเชิงวัตถุ ฉันต้องการย้ำถอยหลัง:
- โดยไม่ต้องสร้างอาร์เรย์ (พิจารณา 0..1000000000)
- ทำงานได้กับทุก Range (เช่น Strings ไม่ใช่แค่จำนวนเต็ม)
- โดยไม่ใช้พลังเชิงวัตถุพิเศษใด ๆ (เช่นไม่มีการดัดแปลงคลาส)
ฉันเชื่อว่าสิ่งนี้เป็นไปไม่ได้หากไม่มีการกำหนดpred
วิธีการซึ่งหมายถึงการแก้ไขคลาส Range เพื่อใช้งาน หากคุณสามารถทำได้โปรดแจ้งให้เราทราบมิฉะนั้นการยืนยันความเป็นไปไม่ได้จะได้รับการชื่นชมแม้ว่ามันจะน่าผิดหวัง บางที Ruby 1.9 จะพูดถึงเรื่องนี้
(ขอบคุณสำหรับเวลาที่อ่านสิ่งนี้)
array#each_with_index
ใช้|value, key|
เพราะชื่อเมธอดมีความหมายของคำสั่งในขณะที่คำสั่งที่ใช้ในการhash#each
เลียนแบบhash[key] = value
ไวยากรณ์?