วิธีที่ถูกต้องในการเติม Array ด้วย Range ใน Ruby


201

ฉันกำลังทำงานผ่านหนังสือที่ให้ตัวอย่างของช่วงการแปลงเป็นอาร์เรย์ที่เทียบเท่าโดยใช้วิธีการ "to_a" ของพวกเขา

เมื่อฉันเรียกใช้รหัสใน irb ฉันได้รับคำเตือนต่อไปนี้

 warning: default `to_a' will be obsolete

ทางเลือกที่ถูกต้องในการใช้ to_a คืออะไร

มีวิธีอื่นในการเติมอาร์เรย์ด้วย Range หรือไม่?


7
caveat ขนาดใหญ่เพื่อแปลงช่วงเป็นอาร์เรย์เป็นช่วงใหญ่สามารถใช้หน่วยความจำจำนวนมากเมื่อสร้างอาร์เรย์ดังนั้นใช้ด้วยความระมัดระวัง แทนที่จะสร้างอาเรย์มันอาจเป็นการดีกว่าที่จะวนซ้ำในช่วงที่คุณต้องการให้อาเรย์หยุดการใช้หน่วยความจำ เป็นหนึ่งในสิ่งที่ "นำไปใช้ตามความจำเป็น"
มนุษย์ดีบุก

คำตอบ:


357

คุณสามารถสร้างอาร์เรย์ด้วยช่วงโดยใช้เครื่องหมาย,

>> a=*(1..10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

ใช้Kernel Arrayวิธีการ

Array (1..10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

หรือใช้ to_a

(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

1
เกิดอะไรขึ้นถ้าอาร์เรย์จะถูกสร้างขึ้นแล้วและคุณต้องการที่จะเพิ่มช่วงไป: order = 1ฉันมี order << (2.25).to_aแล้วก็ แต่นี่สร้างอาเรย์อื่นภายในอาเรย์ฉันแค่ต้องการช่วงจาก 2 ถึง 25 แต่ถ้าฉันลองorder << (2.25)ฉันจะได้รับข้อผิดพลาดไม่สามารถแปลง Range เป็น Integer ได้
kakubei

1
@kakubei ใช้แทนconcat <<นอกจากนี้คุณไม่ควรได้รับ "ไม่สามารถแปลงช่วงเป็นจำนวนเต็ม" ยกเว้นว่าorderเป็นจำนวนเต็ม - ซึ่งในกรณีนี้คุณจะเปลี่ยนบิตไม่ได้ต่อท้ายอาร์เรย์
เคลวิน

3
ตัวเลือก Splat ใช้งานไม่ได้กับ Ruby 1.8.7 ฉันขอแนะนำให้ใช้(1..10).to_aสำหรับความเข้ากันได้แบบย้อนหลัง
kylewelsby

5
การใช้สีแดงของคุณน่ารังเกียจ [*1..10]ตัวเลือกมองที่ดีกว่าคือ
Hauleth

2
วิธีที่เร็วที่สุดคืออะไร?
Andrey Yasinishyn

79

สิ่งนี้ใช้ได้กับฉันใน irb:

irb> (1..4).to_a
=> [1, 2, 3, 4]

ฉันสังเกตเห็นว่า:

irb> 1..4.to_a
(irb):1: warning: default `to_a' will be obsolete
ArgumentError: bad value for range
        from (irb):1

ดังนั้นบางทีคุณหายไปวงเล็บ?

(ฉันใช้ Ruby 1.8.6 patchlevel 114)


7
คำอธิบาย : ไม่มีวงเล็บคุณกำลังเรียกใช้เมธอด to_a จากอินสแตนซ์ของ Fixnum Class (ในกรณีนี้ 4) ไม่ใช่ในช่วง 1..4 หากคุณทำงานFixnum.methods.include?(to_a)ในทับทิม 1.9.2 คุณจะสังเกตเห็นว่าไม่มีการกำหนดวิธี to_a อีกต่อไปดังนั้นทำไมคุณถึงได้รับข้อความการคิดค่าเสื่อมราคาใน 08
Pierre

@ เปียโนฉันคิดว่าคุณหมายถึงFixnum.instance_methods.include?(:to_a)
เคลวิน

@Kelvin - จริง ๆ แล้วmethods.include?มีข้อมูลเพิ่มเติม: $ irb irb(main):001:0> Fixnum.methods.include?(to_a) (irb):1: warning: default to_a 'จะล้าสมัย=> false irb(main):002:0> Fixnum.instance_methods.include?(:to_a) => false
Richard Turner

1
@RichardTurner ฉันถือว่าคุณใช้ทับทิม 1.8 ฉันเกรงว่าคุณจะเข้าใจผิดว่าเกิดอะไรขึ้นกับการto_aเตือนในรูปแบบแรก เป็นเพราะคุณกำลังโทรto_aเข้าself- คุณไม่ได้ตรวจสอบจริง ๆ ว่าto_aเป็นวิธีการของ Fixnum หรือไม่ ลองโทรออกto_aด้วยตัวเองแล้วคุณจะเห็นคำเตือนเดียวกัน
เคลวิน

@Kelvin - Duh! เงินลดลง ขอบคุณ
Richard Turner

34

ดูเหมือนว่าคุณกำลังทำสิ่งนี้:

0..10.to_a

คำเตือนมาจาก Fixnum # to_a ไม่ใช่จากช่วง # to_a ลองใช้สิ่งนี้แทน:

(0..10).to_a



4

ฉันพยายามใช้ช่วงจากจำนวนมากไปหาน้อยและได้ผลลัพธ์ที่ฉันไม่ได้คาดไว้:

irb(main):007:0> Array(1..5)
=> [1, 2, 3, 4, 5]
irb(main):008:0> Array(5..1)
=> []

นั่นเป็นเพราะการใช้งานช่วง
ดังนั้นฉันต้องใช้ตัวเลือกต่อไปนี้:

(1..5).to_a.reverse

4
วันนี้ฉันค้นพบ5.downto(1).to_aซึ่งเป็นอีกวิธีหนึ่งในการแสดงช่วงstackoverflow.com/a/8927009/703903 ที่
odlp
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.