【问题标题】:How to square an array of numbers in ruby without `map` or `collect` methods? [closed]如何在没有`map`或`collect`方法的情况下对ruby中的数字数组进行平方? [关闭]
【发布时间】:2020-12-13 04:02:28
【问题描述】:

这是我目前拥有的代码

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

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

【问题讨论】:

  • 你的代码唯一的问题是你对每个数字求平方,然后不做任何事情,然后它消失在以太中。您是否考虑过将方块存放在某个地方?
  • 您正在丢弃这些值。 eachmap 之间的唯一区别是 each 只是运行块并且不对其返回值做任何事情,而 map 将返回值收集到一个数组中。我不知道您为什么要避免为此使用map
  • 现实世界中哪些可能的场景导致您需要避免map?这是最好、最正确的方法。
  • 谢谢大家的回复,我在课堂上做这件事,这就是练习所要求的。
  • 我记得在 basic 和 c 中的练习要求在不使用 FOR 的情况下进行循环。

标签: arrays ruby math


【解决方案1】:

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,在将每个元素推入(使用&lt;&lt;)到我们的新数组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 调用给定数组的所有生成值,它返回一个包含所述值的数组。

【讨论】:

  • sagarpandya82...谢谢。一切检查...再次感谢
  • 请不要乱扔代码。解释为什么代码是有用的。这是给某人一条鱼或教他们如何钓鱼的区别。帮助他们理解。
【解决方案2】:

如果您不能使用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

【讨论】:

  • +1。 #reduce 是这里的答案。它是一种通用的迭代方法,毕竟凡事#eachfor … in都可以用reduce完成,包括(但不限于)mapgroup_bysortany?all?grep,等等。
【解决方案3】:

您可以使用简单的inject 尝试这种方式。文档参考:INJECT

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

【讨论】:

    【解决方案4】:

    正如在 cmets 中指出的那样,mapcollect 是在 Ruby 中执行此操作的自然方式。但是,如果您只是不得不没有:

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

    【讨论】:

    • 呃,变异参数是big不行,除非绝对必要并且在文档中明确说明。 (我不相信在 Ruby 核心库、Ruby 标准库或任何广泛使用的第三方库中没有一个方法会改变其参数。)
    • map/collect 不要修改任何内容。他们返回一个 new Array。即使他们确实修改了Array,与修改receiver(即玩弄自己的私处)之间仍然存在很大的区别并修改参数(即玩弄别人的私处)。
    【解决方案5】:

    您需要数组元素的索引才能将其设置为其他值,因此我们将使用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>
    

    【讨论】:

      猜你喜欢
      • 2020-01-17
      • 2014-01-23
      • 2014-01-29
      • 1970-01-01
      • 2016-11-05
      • 2013-01-04
      • 1970-01-01
      • 2022-07-27
      相关资源
      最近更新 更多