如何在没有`map`或`collect`方法的情况下对ruby中的数字数组进行平方?

时间:2016-03-21 21:03:37

标签: arrays ruby math

这是我目前的代码

def square_array(array)
    array.each do |i|
      i ** 2
    end
end

我知道这不正确,有人可以向我解释这个过程吗?

5 个答案:

答案 0 :(得分:2)

each<<与空数组一起使用

def square_array(array)
  arr = []
  array.each { |i| arr << i ** 2 }
  arr
end

my_arr = [1, 2]
p square_array(my_arr) #=> [1, 4]

这里我们创建了一个新的空数组arr。然后我们遍历另一个作为参数传递的数组array,在将每个元素(使用<<)推入新数组arr之前对其进行平方。

最后,我们通过简单地将arr写为方法块中的最后一行来返回新创建的数组arr。我们可以编写return arr但在Ruby中可以省略return关键字。

使用each_with_object

上述技术的轻微演变

def square_array(array)
  array.each_with_object([]) { |i,arr| arr << i ** 2 }
end

my_arr = [1, 2]
p square_array(my_arr) #=> [1, 4]

each与枚举器

一起使用
def square_array(array)
  Enumerator.new do |y|
    array.each { |e| y << e ** 2 }    
  end
  .take(array.length)
end

my_arr = [1, 2, 3, 4]
p square_array(my_arr) #=> [1, 4, 9, 16]

这里我们创建一个新的枚举器。然后我们为枚举器编写指令(告诉它),根据each块产生值y。

然后我们使用take调用给定数组的所有生成值,返回一个包含所述值的数组。

答案 1 :(得分:1)

您需要数组元素的索引才能将其设置为其他内容,因此我们将使用each_with_index,并将原始数组元素设置为新值:

irb(main):001:0> j = [2,3,4]
=> [2, 3, 4]
irb(main):002:0> j.each_with_index { |e, i| j[i] = e**2 }
=> [4, 9, 16]
irb(main):003:0>

答案 2 :(得分:1)

如果您无法使用map,那么使用reduce似乎很自然:

def square_array(array)
  array.reduce([]) { |a, n| a << n * n }
end

但如果这违反了限制的精神,你可以用更手动的方式来做:

def square_array(array)
  [].tap do |a|
    array.each do { |n| a << n * n }
  end
end

答案 3 :(得分:0)

您可以使用简单的inject尝试这种方式。对于Doc,请参阅:INJECT

> ar = [2,3,4,5]
=> [2, 3, 4, 5]
> ar.inject([]){|a,b| a << b**2}
=> [4, 9, 16, 25]

答案 4 :(得分:-1)

正如评论中指出的那样,mapcollect是在Ruby中实现它的自然方式。但是,如果你只是 没有:

def square_array(ary)
  a = Array.new(ary.length)
  ary.each_index { |i| a[i] = ary[i] * ary[i] }
  a
end