2009-07-24 49 views
1

| m,k |事情有点让我失望。这与优先顺序有关吗? m代表0(或某些语言中的1),k代表Array/Hash中的最后一个?所以,也许我没有得到Ruby的想法,但我有一个关于Enumerables注入的问题注入

那么为什么人们在.inject()中输入一个数字呢?

另外,是否有一种简单的方法来学习如何使用它,以及它的价值究竟是什么?从这个问题来看,我希望你们都知道我对任何编程语言都很不好,Ruby是我的第一选择。

+1

你有你一个具体的例子” d喜欢解释吗? kjfletch的答案很好,如果你扩大你的问题,有些人可能会提供更多的细节。 – mikej 2009-07-24 07:42:24

回答

5

你似乎混淆块参数与方法参数。

当您使用| m,k |时,人们传入inject()方法的数字是确定“m”的初始值的方法参数。为块。我不知道你在哪里看到他们叫做m和k,或者他们为什么这样命名,但这当然不是因为它们代表了第一个也是最后一个元素。

以kjfletch的链接breakdown of an inject()中描述的方式查看它会更简单一些,它们被命名为“result”和“element”。

使用inject()的值是简洁的能力。任何你想用inject()做的事情都可以通过调用each()方法来完成,并且需要一个更长的块和额外的变量声明。请参阅this question and the answer以了解它。

6

让我们来尝试一个例子。

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_sumnumber

调用的可枚举对象#inject的每个值都会依次作为第二个值传递给该块。在该示例中,number将是3,然后是1,然后4,然后是1,然后是5,然后最后是9。所以在这个例子中,该块将被调用六次; numbers中的每个位置一次。

传递给块(此处名为prefix_sum)的第一个值通常称为累加器。其初始值(该块在第一次被#inject调用时使用的值)由传递给#inject的参数(在本例中为0)设置。块的返回值决定下次调用块时累加器的值(prefix_sum)。

当没有更多要处理的元素时,将返回累加器的值(此处存储在sum中)。

所以通过它我们就漫步:

  • #inject接收0和我们的块。
  • #inject调用我们的块,绑定prefix_sum0(初始累加器值)和number3(第一个数组值)。
  • 我们的区块计算0+33并返回它。
  • #inject调用我们的块,装订prefix_sum3(返回值),并以number1(第二阵列值)
  • 我们的块计算作为3+14并将其返回。
  • #inject调用我们的块,装订prefix_sum4(返回值),并以number4(第三阵列值)
  • 我们的块计算作为4+48并将其返回。
  • #inject调用我们的块,装订prefix_sum8(返回值),并以number1(第四数组值)
  • 我们的块计算作为8+19并将其返回。
  • #inject调用我们的块,装订prefix_sum9(返回值),并以number5(第五数组值)
  • 我们的块计算作为9+514并将其返回。
  • #inject调用我们的块,装订prefix_sum14(返回值),并以number9(第六数组值)
  • 我们的块计算作为14+923并将其返回。
  • 因为没有更多的数组元素,#inject返回23,我们将sum绑定为该值。

你可以看一下注射的项目清单上的圆括号的操作,在这个例子中,caluculating:

((((((0 + 3) + 1) + 4) + 1) + 5) + 9) 

这可以让你把它通常只在一对参数进行操作的任何操作,并将其应用于列表。

+0

+1很好的解释 – 2009-07-24 16:38:37

2

如果您想了解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 
0

为了完整性:通常意味着备忘录; k可能意味着(经常与v一起使用,这意味着)。因此,举例来说:

stuff.inject({}) { |m,(k,v)| m.merge(k.to_sym => v) } 

我也看到了人们使用一个蓄电池和元素é,像这样:

numbers.inject { |a,e| a+e } 
相关问题