2009-07-24 68 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 } 
相關問題