| m,k |事情有点让我失望。这与优先顺序有关吗? m代表0(或某些语言中的1),k代表Array/Hash中的最后一个?所以,也许我没有得到Ruby的想法,但我有一个关于Enumerables注入的问题注入
那么为什么人们在.inject()中输入一个数字呢?
另外,是否有一种简单的方法来学习如何使用它,以及它的价值究竟是什么?从这个问题来看,我希望你们都知道我对任何编程语言都很不好,Ruby是我的第一选择。
| m,k |事情有点让我失望。这与优先顺序有关吗? m代表0(或某些语言中的1),k代表Array/Hash中的最后一个?所以,也许我没有得到Ruby的想法,但我有一个关于Enumerables注入的问题注入
那么为什么人们在.inject()中输入一个数字呢?
另外,是否有一种简单的方法来学习如何使用它,以及它的价值究竟是什么?从这个问题来看,我希望你们都知道我对任何编程语言都很不好,Ruby是我的第一选择。
你似乎混淆块参数与方法参数。
当您使用| m,k |时,人们传入inject()方法的数字是确定“m”的初始值的方法参数。为块。我不知道你在哪里看到他们叫做m和k,或者他们为什么这样命名,但这当然不是因为它们代表了第一个也是最后一个元素。
以kjfletch的链接breakdown of an inject()中描述的方式查看它会更简单一些,它们被命名为“result”和“element”。
使用inject()的值是简洁的能力。任何你想用inject()做的事情都可以通过调用each()方法来完成,并且需要一个更长的块和额外的变量声明。请参阅this question and the answer以了解它。
让我们来尝试一个例子。
numbers = [ 3, 1, 4, 1, 5, 9 ]
sum = numbers.inject(0) do |prefix_sum, number|
prefix_sum + number
end
#inject
带一个参数和一个块。该块应该取两个值,并返回一个新值。
在上面的例子中,#inject
的参数是0
,而块是do |prefix_sum, number| prefix_sum + number end
。将传递给块的值在两个|
标记之间命名: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
绑定为该值。你可以看一下注射的项目清单上的圆括号的操作,在这个例子中,caluculating:
((((((0 + 3) + 1) + 4) + 1) + 5) + 9)
这可以让你把它通常只在一对参数进行操作的任何操作,并将其应用于列表。
+1很好的解释 – 2009-07-24 16:38:37
如果您想了解Ruby中的任何方法,可以使用捆绑的ri
工具(因此您可以键入“ri Enumerable.inject”查找文档)或搜索Ruby-Doc。在这种情况下,您可以使用see:
通过将块应用于累加器值(备注)和每个元素,组合enum的元素。在每一步中,备忘录都设置为该块返回的值。第一种形式可以让您提供备忘录的初始值。第二种形式使用集合的第一个元素作为初始值(并在迭代时跳过该元素)。
# Sum some numbers
(5..10).inject {|sum, n| sum + n } #=> 45
# Multiply some numbers
(5..10).inject(1) {|product, n| product * n } #=> 151200
# find the longest word
longest = %w{ cat sheep bear }.inject do |memo,word|
memo.length > word.length ? memo : word
end
longest #=> "sheep"
# find the length of the longest word
longest = %w{ cat sheep bear }.inject(0) do |memo,word|
memo >= word.length ? memo : word.length
end
longest #=> 5
为了完整性:米通常意味着备忘录; k可能意味着键(经常与v一起使用,这意味着值)。因此,举例来说:
stuff.inject({}) { |m,(k,v)| m.merge(k.to_sym => v) }
我也看到了人们使用一个为蓄电池和元素é,像这样:
numbers.inject { |a,e| a+e }
你有你一个具体的例子” d喜欢解释吗? kjfletch的答案很好,如果你扩大你的问题,有些人可能会提供更多的细节。 – mikej 2009-07-24 07:42:24