Cách chính xác để tạo một Mảng có Phạm vi trong Ruby


201

Tôi đang làm việc thông qua một cuốn sách đưa ra các ví dụ về Phạm vi được chuyển đổi thành các mảng tương đương bằng các phương thức "to_a" của chúng

Khi tôi chạy mã trong irb, tôi nhận được cảnh báo sau

 warning: default `to_a' will be obsolete

Sự thay thế chính xác cho việc sử dụng to_a là gì?

Có cách nào khác để điền vào một mảng với Phạm vi không?


7
Sự cảnh báo lớn để chuyển đổi một phạm vi thành một mảng, là một phạm vi lớn có thể tiêu tốn rất nhiều bộ nhớ khi mảng được xây dựng, vì vậy hãy cẩn thận sử dụng nó. Thay vì tạo mảng, có thể tốt hơn là lặp lại phạm vi như bạn sẽ làm một mảng để giảm mức tiêu thụ bộ nhớ. Đó là một trong những điều "áp dụng khi cần thiết".
Tin Man

Câu trả lời:


357

Bạn có thể tạo một mảng với một phạm vi bằng splat,

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

sử dụng Kernel Arrayphương pháp,

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

hoặc sử dụng to_a

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

1
Điều gì xảy ra nếu mảng đã được tạo và bạn muốn thêm một phạm vi vào nó: Tôi có order = 1. Sau đó order << (2.25).to_a. Nhưng điều này tạo ra một mảng khác bên trong mảng, tôi chỉ đơn giản muốn phạm vi từ 2 đến 25. Tuy nhiên, nếu tôi thử order << (2.25)tôi gặp lỗi không thể chuyển đổi Range thành Integer.
kakubei

1
@kakubei dùng concatthay <<. Ngoài ra, bạn không nên nhận "không thể chuyển đổi Phạm vi thành Số nguyên" trừ khi orderlà số nguyên - trong trường hợp đó, bạn sẽ thay đổi bit, không nối thêm mảng.
Kelvin

3
tùy chọn Splat không hoạt động cho Ruby 1.8.7, tôi khuyên bạn nên sử dụng (1..10).to_ađể tương thích ngược
kylewelsby

5
Việc sử dụng splat của bạn là khó chịu. Lựa chọn tốt hơn là [*1..10].
Hauleth

2
cách nhanh nhất là gì ??
Andrey Yasinishyn

79

Điều này làm việc cho tôi trong irb:

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

Tôi nhận thấy rằng:

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

Vì vậy, có lẽ bạn đang thiếu dấu ngoặc đơn?

(Tôi đang chạy Ruby 1.8.6 patchlevel 114)


7
Giải thích : không có dấu ngoặc đơn, bạn đang gọi phương thức to_a từ một thể hiện của Lớp Fixnum (trong trường hợp này là 4), không phải trong phạm vi 1..4. Nếu bạn chạy Fixnum.methods.include?(to_a)trong ruby ​​1.9.2, bạn sẽ nhận thấy rằng phương thức to_a không còn được xác định, do đó tại sao bạn lại nhận được thông báo khấu hao đó trong 08
Pierre

@Pierre Tôi nghĩ bạn có nghĩa làFixnum.instance_methods.include?(:to_a)
Kelvin

@Kelvin - Trên thực tế, methods.include?có nhiều thông tin hơn: $ irb irb(main):001:0> Fixnum.methods.include?(to_a) (irb):1: warning: default to_a 'sẽ lỗi thời=> false irb(main):002:0> Fixnum.instance_methods.include?(:to_a) => false
Richard Turner

1
@RichardTurner Tôi giả sử bạn đang sử dụng ruby ​​1.8. Tôi sợ bạn hiểu nhầm những gì kích hoạt to_acảnh báo ở dạng đầu tiên. Đó là bởi vì bạn đang gọi điện thoại to_atrên self- bạn đang không thực sự kiểm tra xem to_alà một phương pháp Fixnum. Hãy thử tự gọi to_avà bạn sẽ thấy cảnh báo tương tự.
Kelvin

@Kelvin - Duh! Những đồng xu rơi. Cảm ơn.
Richard Turner

34

Âm thanh như bạn đang làm điều này:

0..10.to_a

Cảnh báo là từ Fixnum # to_a, không phải từ Range # to_a. Hãy thử điều này thay thế:

(0..10).to_a

9

Kiểm tra điều này:

a = [*(1..10), :top, *10.downto( 1 )]

2
* 10.dftimeo (1) là những gì tôi đang tìm kiếm, cảm ơn bạn!
Daniel


4

Tôi chỉ cố gắng sử dụng phạm vi từ lớn hơn đến nhỏ hơn và nhận được kết quả mà tôi không mong đợi:

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

Đó là vì phạm vi triển khai.
Vì vậy, tôi đã phải sử dụng tùy chọn sau:

(1..5).to_a.reverse

4
Hôm nay tôi phát hiện ra 5.downto(1).to_ađó là một cách khác để thể hiện phạm vi stackoverflow
dần.com/a/8927009/703903
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.