为正负n创建从0到n的数字数组

时间:2015-05-21 16:49:51

标签: arrays ruby

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

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

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

7 个答案:

答案 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)

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

(我在这里展示了一个独立的方法,而不是修补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删除条件。它通过分别返回ab-1来确定0是否小于,等于或大于+1

更具体地说,对于Fixnum#<=>,如果n <=> 0大于1n会返回0-1n }小于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等于0n会返回0,但这并不重要,因为在那里结果数组为[0]0 * 0仍为0

的情况

作为一种方法:

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

虽然它很短,但这种方法变得非常复杂,并且它的作用并不明显。因此,我更喜欢第一种方法(使用uptodownto的方法),因为它很简单。

答案 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]