给出“Array.new(10){| e | e = e * 2}”的Array#new工作的块形式如何?

时间:2016-03-24 19:35:59

标签: arrays ruby constructor ruby-block

我无法理解花括号内的部分。

Array.new(10) { |e| e = e * 2 }
# => [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]   

我知道创建了一个包含十个值的新数组,但是后半部分是做什么的?

2 个答案:

答案 0 :(得分:5)

让我们详细介绍一下:

nums = Array.new(10)

这将创建一个包含10个元素的新数组。对于每个数组元素,它将控制权传递给由以下指定的块:

{ |e| e = e * 2 }

|e|表示元素的索引。索引是数组中的位置。这从0开始,到9结束,因为数组有10个元素。第二部分将索引乘以2并返回该值。这是因为返回了作为块中最后一个语句的e * 2然后将返回的值应用于该元素的值。因此我们最终得到以下数组:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

修改

正如pjs所提到的那样,为了避免出现问题,编写相同代码的更简单方法是:

Array.new(10) { |e| e * 2 }

答案 1 :(得分:2)

您的代码

nums = Array.new(10) { |e| e = e * 2 }

在IRB或Pry中逐步分解,看看你的代码到底在做什么。例如:

  1. Array.new(10)创建一个包含10个元素的数组。
  2. Array.new(10) { |e| puts e }打印每个元素的索引,该索引将为0..9。
  3. 构造{ |e| e = e * 2 }或更具惯用性{ |e| e * 2 }是一个Ruby块,它将传递给块变量 e 的每个元素的索引乘以2。
  4. nums = Array.new(10) { |e| e = e * 2 }获取块的结果并将其存储在变量 nums 中。
  5. 请注意,这个存储的数组是通过Array#new的块形式创建的,它表示在使用构造函数的块形式时:

      

    [A]创建给定大小的数组。通过将元素的索引传递给给定块并存储返回值来创建此数组中的每个元素。

    原帖中的示例肯定是有效的Ruby代码,但不是特别清楚。使用更明确的代码可以获得相同的结果,例如下面的示例。

    许多更清晰的替代方案之一

    总有不止一种方法可以做,特别是在Ruby中。如果您想更明确地了解您的代码正在做什么,请使用更少的"魔法"构造。例如,您的代码大致相当于:

    num_array = 0.upto(9).map { |int| int * 2 }
    #=> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]