关于注入方法:它是如何工作的?

这部分代码计算每个算术系列的值,包括用户输入的数字:

print "enter a number: "
num = gets.to_i
(1..num).inject(0) do |res, e|
  res += e
  p res
end

我认为 (1..num) 是范围, num 是用户输入 . 我知道 inject 通过应用由块或命名方法或运算符的符号指定的二进制操作来组合枚举的所有元素 .

我不明白这行中的每个元素是做什么的:

(1..num).inject(0) do |res, e|
  • |res, e| 是什么意思?它必须是定义 inject 的内容的块,但例如 rese 代表什么? ( e 可能是元素?)

  • (0) 代表什么?

  • 命令 do 做什么?

  • 关于 (1..num)inject(0) 的连接是什么?

  • 我是否正确地认为 p 在最后只代表 putsprint

回答(3)

2 years ago

inject 采用可选的起始值,以及采用中间值和元素并返回新的中间值的块 .

所以:

(0)代表什么?

起始值参数为 inject .

命令“做”有什么作用?

这不是命令;它标志着块的开始(由 end 终止) . .inject(0) do ... end 几乎(除了一些句法问题)与 .inject(0) { ... } 相同 . 通常, do ... end 用于多行块, { ... } 用于单行块,但不是一般规则 .

什么是| res,e |意思?

这些是块参数(中间值和当前元素),这里可能分别在“结果”和“元素”之后调用 .

让我们看一个简化的例子: (1..3).inject(0) do |res, e| res + e end 将中间结果设置为 0 . 然后它将传递此中间结果并注入可枚举的第一个元素: res0e1 . 块的值是其最后一个表达式的值,即 10 + 1 的结果) . 此 1 现在成为新的中间值, 2 成为下一个当前元素 . 块的值是 31 + 2 的结果) . 在下一次迭代中,中间值为 3 ,当前元素也为 3 ,从而产生 63 + 3 ) . 当我们到达其上边界时,范围将停止产生元素,并且 inject 返回并计算最后的中间结果 6 .

另外,最后一个问题我是否正确地假设最后的“p”代表看跌或打印?

几乎 . p 是它自己的野兽 . p xputs x.inspect; x 大致同义 - 即它以不同的格式打印值,与 puts 总是返回 nil 不同, p 返回值不变 . 因此,块的末尾 p res 不会通过使代码返回 nil 来破坏代码,而是透明地返回 res .

2 years ago

inject 是一种将集合(例如数组或范围)简化为单个值的方法 . 它通过对集合中的每个元素执行一次块来完成此操作 . 该块有两个参数:正在处理的当前值,以及最终将返回的单个值 . inject 本身采用一个参数(除了块),这是它的初始起始值 .

举个例子 .

x = [1, 2, 3, 4, 5].inject(0) do |result, current|
  result + current
end

我们有一个数字列表, [1, 2, 3, 4, 5] . 我们要把它们煮成一个单一的数字 .

我们从 0 开始,因为那是 inject 的论点 . 这意味着块第一次运行时, result 将为0 .

所以该块第一次运行 . result 是0, current 是1,第一个元素 . 我们说 result + current (这是 1 ) . 它's the last expression inside the block, so it' s阻止'returns' .

在街区结束时, inject 说"Okay, do we have more elements in the collection?"是的 . 所以块再次运行 . 这次, result 是返回的最后一个块,即1,而 current 是第二个元素 2 .

该块运行,并以 result + current 或1 2结束,即3 . 仍有剩余元素,因此我们再次运行 . 这一次, result 是3, current 是3. result + current ,6 . 还有更多的值,下次运行时 result 是6而 current 是4. 6 4 = 10.还有更多的值,下次运行 result 是10和 current 是5. 10 5 = 15 .

然后块完成,并且没有剩余的元素 . 所以 inject 本身返回的是最终值15.所以最后, x = 15 . 我们通过添加内容将我们的列表归结为一个数字 .

示例中的 res 代表结果, e 代表元素 . 你可以随便给他们打电话 . 你可以在添加时将它们称为 sum ,或者如果相乘则称为 product . 但他们不一定是数字 . 你可以使用 inject 来煮沸一个字符串数组,一系列字符,一个数组数组,你想要的任何集合 . 该块只是告诉它如何 .

2 years ago

很高兴看到你正在学习Ruby,欢迎!

在您的专业水平上,最好从中学习书 .

一些快速的答案

  • 1..num 是一个范围对象

  • .inject(0) do ... end 是一个带有两个参数的方法调用,值 0 和一个代码块

  • do |a, b| ... end 是一个包含两个参数的代码块

  • rese 是非常糟糕的变量名称,也许更好用 sumeach

  • p 是一个打印调试信息的全局方法,类似于 puts 但不一样

希望有助于解锁你 .