创建从 0 到 n 的数字数组,表示正 n 和负 n

Pad*_*wan 5 ruby arrays

鉴于n,我想创建一个从0到 的数组n

10.make_array #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)

如果是负数,它也应该起作用n

-10.make_array #=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10]
Run Code Online (Sandbox Code Playgroud)

我已经编写了这段代码,但我认为我让它变得比必要的更复杂(它不适用于负数):

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
Run Code Online (Sandbox Code Playgroud)

有没有更简单的方法或捷径来做同样的事情,以及关于如何处理负数的任何建议?

Yu *_*Hao 5

用一个Range

(0 .. 10).to_a
#=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)

处理负数不是问题:

(-10 .. -1).to_a
#=> [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1]
Run Code Online (Sandbox Code Playgroud)


Ste*_*fan 2

要支持负数,您可以使用uptoanddownto以及条件:

(我在这里展示一个独立的方法而不是修补Integer

def make_array(n)
  if n > 0
    0.upto(n).to_a
  else
    0.downto(n).to_a
  end
end
Run Code Online (Sandbox Code Playgroud)

上面创建了一个枚举器,该枚举器使用 转换为数组Enumerable#to_a

您可能想通过直接调用来跳过中间对象(枚举器)Array::new- 它创建一个具有给定元素数量的数组:

n = 3
Array.new(n) #=> [nil, nil, nil]
Run Code Online (Sandbox Code Playgroud)

如果给定了一个块,它将每个元素的索引传递给该块,我们应该返回它的值。该索引实际上正是我们想要的,因此我们可以简单地返回它:

Array.new(n) { |i| i } #=> [0, 1, 2]
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,Array.new(n)返回n元素,但我们需要n + 1,所以让我们解决这个问题:

Array.new(n + 1) { |i| i } #=> [0, 1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

不幸的是,Array::new不接受负尺寸:

Array.new(-3) #=> negative array size (ArgumentError)
Run Code Online (Sandbox Code Playgroud)

因此,对于负数,n我们必须传递-n并返回-i

n = -3
Array.new(-n + 1) { |i| -i } #=> [0, -1, -2, -3]
Run Code Online (Sandbox Code Playgroud)

作为一种方法:

def make_array(n)
  if n > 0
    Array.new(n + 1) { |i| i }
  else
    Array.new(-n + 1) { |i| -i }
  end
end
Run Code Online (Sandbox Code Playgroud)

让我们尽量避免重复。

转换n为正数很容易使用abs

3.abs  #=> 3
-3.abs #=> 3
Run Code Online (Sandbox Code Playgroud)

应用于我们的代码:

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]
Run Code Online (Sandbox Code Playgroud)

对于块,我们可以使用三元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]
Run Code Online (Sandbox Code Playgroud)

我们甚至可以使用 spaceship 运算符来删除该条件a <=> b。它通过分别返回、或来确定是否a小于、等于或大于。b-10+1

更具体地说,对于Fixnum#<=>,如果大于,则n <=> 0返回,如果小于:1n0-1n0

3 <=> 0  #=> 1
-3 <=> 0 #=> -1
Run Code Online (Sandbox Code Playgroud)

我们可以<=>在块中使用 的结果来乘以i

Array.new(n.abs + 1) { |i| i * (n <=> 0) }
Run Code Online (Sandbox Code Playgroud)

这相当于i * 1(if n > 0) 或i * -1(if n < 0)。

(还有第三个返回值:如果等于则n <=> 0返回,但这并不重要,因为在这种情况下,结果数组仍然是)0n0[0]0 * 00

作为一种方法:

def make_array(n)
  Array.new(n.abs + 1) { |i| i * (n <=> 0) }
end
Run Code Online (Sandbox Code Playgroud)

虽然很短,但这个方法变得相当复杂,并且不明显在做什么。因此,我更喜欢第一种方法(使用upto和 的方法downto),因为它简单。