在Ruby中使用范围填充数组的正确方法


201

我正在读一本书,其中提供了使用“ to_a”方法将范围转换为等效数组的示例

当我在irb中运行代码时,出现以下警告

 warning: default `to_a' will be obsolete

什么是使用to_a的正确选择?

有其他方法可以用Range填充数组吗?


7
将范围转换为数组的最大警告是,构建数组时,较大的范围会占用大量内存,因此请谨慎使用。与其创建数组,不如创建一个数组,以降低内存消耗,最好遍历整个范围。这是那些“按需应用”的事物之一。
Tin Man'7

Answers:


357

您可以使用splat创建具有范围的数组,

>> 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 2011年

1
@kakubei使用concat代替<<。另外,除非order是整数,否则您不应该得到“无法将Range转换为Integer” 的信息-在这种情况下,您将进行位移位,而不是数组附加。
开尔文2012年

3
Splat选项不适用于Ruby 1.8.7,建议(1..10).to_a向后兼容使用
kylewelsby 2013年

5
您对splat的使用令人讨厌。更好看的选择是[*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补丁程序级别114)


7
说明:没有括号,您是从Fixnum类的实例(在本例中为4)的实例中调用to_a方法,而不是在1..4范围内。如果您Fixnum.methods.include?(to_a)在ruby 1.9.2中运行,您会注意到to_a方法不再定义,因此,为什么在08
Pierre

@Pierre我想你的意思是Fixnum.instance_methods.include?(:to_a)
Kelvin

@Kelvin-实际上,methods.include?它提供的信息更多:$ irb irb(main):001:0> Fixnum.methods.include?(to_a) (irb):1: warning: default to_a'将作废-Richard => false irb(main):002:0> Fixnum.instance_methods.include?(:to_a) => false
Turner

1
@RichardTurner我假设您正在使用ruby 1.8。恐怕您误解了触发to_a第一种形式的警告的原因。这是因为你调用to_aself-你实际上并没有检查是否to_a是Fixnum对象的方法。尝试to_a自行致电,您将看到相同的警告。
开尔文2012年

@Kelvin-h!一分钱下降。谢谢。
理查德·特纳

34

听起来您正在这样做:

0..10.to_a

该警告来自Fixnum#to_a,而不是Range#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)
=> []

那是因为range实现。
所以我不得不使用以下选项:

(1..5).to_a.reverse

4
今天,我发现5.downto(1).to_a这是表达范围减小的另一种方式stackoverflow.com/a/8927009/703903
odlp
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.