所以也许我在 Ruby 中没有得到这个想法,但我有一个关于 Enumerables 注入的问题
|m,k| 事情有点让我失望。 这和优先顺序有关系吗? m 代表 0(或某些语言中的 1),k 代表数组/哈希中的最后一个?
那么为什么人们要在 .inject() 中输入一个数字呢?
或者,是否有一种简单的方法来学习如何使用它,以及它的确切价值是什么? 从这个问题来看,我希望你们都知道我对任何编程语言都很菜鸟,而 Ruby 是我的第一选择。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
让我们尝试一个例子。
#inject
采用一个参数和一个块。 该块应该采用两个值,并返回一个新值。在上面的示例中,
#inject
的参数是0
,块是do |prefix_sum, number| prefix_sum + 数字结尾
。 将传递到块的值在两个|
标记之间命名:prefix_sum
和number
。调用的可枚举
#inject
的每个值都会作为第二个值依次传递给块。 在此示例中,number
将依次为3
、1
、4
、1
>,然后是5
,最后是9
。 所以在这个例子中,该块将被调用六次; 对于numbers
中的每个位置一次。传递给块的第一个值(此处名为
prefix_sum
)通常称为累加器。 它的初始值,即#inject
第一次调用该块时使用的值,由传递给#inject
的参数设置(在本例中,0 )。 该块的返回值确定下一次调用该块的累加器 (
prefix_sum
) 的值。当没有更多元素需要处理时,将返回累加器的值(此处存储在
sum
中)。那么让我们来看看它:
#inject
接收0
和我们的块。#inject
调用我们的块,将prefix_sum
绑定到0
(初始累加器值),并将number
绑定到3
(第一个数组值)。0+3
计算为3
并返回它。#inject
调用我们的块,将prefix_sum
绑定到3
(返回值),并将number
绑定到1
(第二个数组值)3+1
计算为4
并返回它。#inject
调用我们的块,将prefix_sum
绑定到4
(返回值),并将number
绑定到4
(第三个数组值)4+4
计算为8
并返回它。#inject
调用我们的块,将prefix_sum
绑定到8
(返回值),并将number
绑定到1
(第四个数组值)8+1
计算为9
并返回它。#inject
调用我们的块,将prefix_sum
绑定到9
(返回值),并将number
绑定到5
(第五个数组值)9+5
计算为14
并返回它。#inject
调用我们的块,将prefix_sum
绑定到14
(返回值),并将number
绑定到9
(第六个数组值)14+9
计算为23
并返回它。#inject
返回23
,并且我们将sum
绑定为该值。您可以将注入视为对项目列表进行括号括起来的操作,在本例中,计算:
这使您可以采用通常仅对一对参数进行操作的任何操作,并将其应用于列表。
Let's try an example.
#inject
takes one argument and a block. The block should take two values, and return a new value.In the above example, the argument to
#inject
is0
, and the block isdo |prefix_sum, number| prefix_sum + number end
. The values that will be passed to the block are named in between the two|
markers:prefix_sum
andnumber
.Each value of the enumerable
#inject
was called on is passed as the second value to the block in turn. In this examplenumber
will be3
, then1
, then4
, then1
, then5
, then finally9
. So in this example, the block will be invoked six times; once for each position innumbers
.The first value passed to a block (here named
prefix_sum
) is usually called an accumulator. Its initial value, the value used the first time the block is called by#inject
, is set by the argument passed to#inject
(in this example,0
). The return value of the block determines the value of the accumulator (prefix_sum
) for the next invocation of the block.When there are no more elements to process, the value of the accumulator is returned (and here stored in
sum
).So lets walk through it:
#inject
receives0
and our block.#inject
invokes our block, bindingprefix_sum
to0
(the initial accumulator value) andnumber
to3
(the first array value).0+3
as3
and returns it.#inject
invokes our block, bindingprefix_sum
to3
(the returned value) andnumber
to1
(the second array value)3+1
as4
and returns it.#inject
invokes our block, bindingprefix_sum
to4
(the returned value) andnumber
to4
(the third array value)4+4
as8
and returns it.#inject
invokes our block, bindingprefix_sum
to8
(the returned value) andnumber
to1
(the fourth array value)8+1
as9
and returns it.#inject
invokes our block, bindingprefix_sum
to9
(the returned value) andnumber
to5
(the fifth array value)9+5
as14
and returns it.#inject
invokes our block, bindingprefix_sum
to14
(the returned value) andnumber
to9
(the sixth array value)14+9
as23
and returns it.#inject
returns23
, and we bindsum
to be that value.You can look at inject as parenthesizing an operation on a list of items, in this example, caluculating:
This lets you take any operation which normally only operates on a pair of arguments, and apply it to a list.
您似乎将块参数与方法参数混淆了。
人们传递给inject()方法的数字是一个方法参数,当您使用|m,k|时,它确定“m”的初始值。 对于块。 我不知道你在哪里看到它们被命名为 m 和 k,也不知道它们为什么这么命名,但这肯定不是因为它们代表第一个和最后一个元素。
按照 kjfletch 链接中描述的方式查看它会更简单,细分一个inject(),它们被命名为“result”和“element”。
使用inject() 的价值在于能够简洁。 您想要使用inject() 做的任何事情也可以通过调用each() 方法来完成,使用更长的块和额外的变量声明。 请参阅此问题和答案来感受一下。
You seem to be confusing block arguments with method arguments.
The number people pass into the inject() method is a method argument that determines the initial value for "m" when you use |m,k| for the block. I don't know where you saw them named m and k, or why they were named so, but it's certainly not because they stand for the first and last element.
It would be simpler to look at it in the way described in kjfletch's link, breakdown of an inject(), where they're named "result" and "element" instead.
The value in using inject() is the ability to be concise. Anything you want to do with inject() could also be done with a call to the each() method, with a much longer block, and extra variable declarations. See this question and the answer to get a feeling for it.
如果您想了解 Ruby 中任何方法的作用,可以使用捆绑的 ri 工具(这样您就可以输入“ri Enumerable.inject”来查找文档)或搜索 Ruby-Doc。 在这种情况下,您将看到:
If you want to find out what any method does in Ruby, you can use the bundled
ri
tool (so you could type "ri Enumerable.inject" to look up the docs) or search Ruby-Doc. In this case, you would see:|x,y| 使用块时使用。 当调用yield语句时,你告诉它把调用变量映射到x和y。
请参阅此处 块和产量
请参阅此处的 inject() 调用的详细信息。
The |x,y| are used when using blocks. When the yield statement is called you tell it to map the calling variables to x and y.
Look here Blocks and Yield
See here for a breakdown of an inject() call.
为了完整起见:m 通常表示 memo; k 可能表示键(通常与v 一起使用,表示值)。 例如:
我还看到人们使用 a 表示 accumulator 和 e 表示元素,如下所示:
For completeness: m usually means memo; k may mean key (often uses in conjunction with v, which means value). So, for example:
I've also seen people use a for accumulator and e for element, like this: