鉴于n
,我想创建一个从0
到n
的数组:
10.make_array #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
如果n
为否定,它也应该有效:
-10.make_array #=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10]
我已经编写了这段代码,但我认为我使它变得比必要的更复杂(它对负数不起作用):
class Fixnum
define_method(:make_array) do
my_array = []
self.times() do |count|
self.>(0)
my_array.push(count)
end
my_array.push(self)
my_array
end
end
是否有更简单的方法或捷径可以做同样的事情,以及有关如何处理负数的任何建议?
答案 0 :(得分:2)
使用Range
:
(0 .. 10).to_a
#=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
处理负数不是问题:
(-10 .. -1).to_a
#=> [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1]
答案 1 :(得分:1)
您可以使用Ruby Array方法。
Array.new(11) {|i| i} #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
第一个参数是您要创建的元素数,您可以使用该块来定义每个项目的内容。
更多例子:
Array.new(10) #=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
Array.new(3) {5} #=> [5, 5, 5]
Array.new(8) {|i| i * 2} #=> [0, 2, 4, 6, 8, 10, 12, 14]
来源:http://ruby-doc.org/core-2.2.0/Array.html#class-Array-label-Creating+Arrays
答案 2 :(得分:1)
您可以尝试以下代码:[*1..10]
答案 3 :(得分:1)
您打算将其添加到Fixnum
class Fixnum
define_method(:make_array) do
Array.new(self + 1) {|i| i}
end
end
p 3.make_array # => [0, 1, 2, 3]
对于负数,这将抛出异常,除了-1将产生一个空数组。
<强>附录强>
在注意到sawa关于处理负数的编辑之后,以下工作:
class Fixnum
define_method(:make_array) do
self < 0 ? Array.new(-self + 1) {|i| -i} : Array.new(self + 1) {|i| i}
end
end
-5.make_array # => [0, -1, -2, -3, -4, -5]
答案 4 :(得分:1)
(我在这里展示了一个独立的方法,而不是修补Integer
)
def make_array(n)
if n > 0
0.upto(n).to_a
else
0.downto(n).to_a
end
end
上面创建了一个使用Enumerable#to_a
转换为数组的枚举器。
您可能希望通过直接调用Array::new
来跳过中间对象(枚举器) - 它会创建一个包含给定数量元素的数组:
n = 3
Array.new(n) #=> [nil, nil, nil]
如果给出了一个块,它会将每个元素的索引传递给块,我们应该返回它的值。 index 实际上就是我们想要的,所以我们可以简单地返回它:
Array.new(n) { |i| i } #=> [0, 1, 2]
正如您所看到的,Array.new(n)
会返回n
个元素,但我们需要n + 1
,所以让我们解决这个问题:
Array.new(n + 1) { |i| i } #=> [0, 1, 2, 3]
不幸的是,Array::new
并不接受负面尺寸:
Array.new(-3) #=> negative array size (ArgumentError)
因此,对于否定的n
,我们必须通过-n
并返回-i
:
n = -3
Array.new(-n + 1) { |i| -i } #=> [0, -1, -2, -3]
作为一种方法:
def make_array(n)
if n > 0
Array.new(n + 1) { |i| i }
else
Array.new(-n + 1) { |i| -i }
end
end
让我们尽量避免重复。
使用abs
:
n
转换为正数
3.abs #=> 3
-3.abs #=> 3
应用于我们的代码:
n = 3
Array.new(n.abs + 1) { |i| i } #=> [0, 1, 2, 3]
n = -3
Array.new(n.abs + 1) { |i| i } #=> [0, 1, 2, 3]
对于块,我们可以使用ternary if
:
n = 3
Array.new(n.abs + 1) { |i| n > 0 ? i : -i } #=> [0, 1, 2, 3]
n = -3
Array.new(n.abs + 1) { |i| n > 0 ? i : -i } #=> [0, -1, -2, -3]
我们甚至可以使用太空飞船运营商a <=> b
删除条件。它通过分别返回a
,b
或-1
来确定0
是否小于,等于或大于+1
。
更具体地说,对于Fixnum#<=>
,如果n <=> 0
大于1
,n
会返回0
,-1
会n
}小于0
:
3 <=> 0 #=> 1
-3 <=> 0 #=> -1
我们可以在块中使用<=>
的结果将i
乘以:
Array.new(n.abs + 1) { |i| i * (n <=> 0) }
这相当于i * 1
(如果n > 0
)或i * -1
(如果n < 0
)。
(第三个返回值:如果n <=> 0
等于0
,n
会返回0
,但这并不重要,因为在那里结果数组为[0]
且0 * 0
仍为0
)
作为一种方法:
def make_array(n)
Array.new(n.abs + 1) { |i| i * (n <=> 0) }
end
虽然它很短,但这种方法变得非常复杂,并且它的作用并不明显。因此,我更喜欢第一种方法(使用upto
和downto
的方法),因为它很简单。
答案 5 :(得分:1)
class Fixnum
def sequence_from_zero
0.step(self, self/self.abs).to_a
end
end
p 10.sequence_from_zero # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
p -10.sequence_from_zero # => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10]
答案 6 :(得分:0)
您还可以使用Fixnum#upto
:
$ ruby -e "p 1.upto(10).to_a"
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]