剛接觸inject時,對其瞭解不是很深,直看到這篇文章 ruby-inject,才有了新的認識,文章配合大量例子進行說明。
1、先看最簡單的求和例子,我們從這裡分析inject的實現機制。
Ruby代碼
- [1, 2, 3, 4].inject(0) { |result, element| result + element } # => 10
inject帶有一個參數和block。block中的兩個參數是有含義的。第一個參數reslut在inject第一次執行block時把inject帶的參數付值給它,element就是數組中的元素,該例中inject一共執行4次block,每次執行block完後,最後語句的結果再付值給result,如此迴圈,直到遍曆數組中所有元素。我們深入這個例子看每一步執行的結果。
因為數組有4個元素,所以要執行4次block操作:
第一次操作:result=0,既等於inject帶的參數;element=1,既第一個元素;執行block後result + element =1,再把這個結果付值給result,所以在執行完第一次block後,result = 1。
第二次操作:result=1,既上次運行block後的最後一條語句的結果;element=2,既第二個元素;執行block後付值result=3。
如此類推,直到最後一次執行完block,生產的值為10。就是inject的傳回值了。
inject可以不帶參數,此時result的初始值為數組元素的第一個值。所以上例可改寫成:
Ruby代碼
- [1, 2, 3, 4].inject{ |result, element| result + element }
這時執行block的次數為3次。
文章中還提到也其它用法:
Ruby代碼
- hash = [[:first_name, 'Shane'], [:last_name, 'Harvie']].inject({}) do |result, element|
- result[element.first] = element.last
- result
- end
-
- hash # => {:first_name=>"Shane", :last_name=>"Harvie"}
把array轉換成hash表。有也第一個例子的基礎,這個例子應該很容易看得懂。
再看一個例子,需要對一數組元素進行過濾並進行一些加工,
Ruby代碼
- [1, 2, 3, 4, 5, 6].select { |element| element % 2 == 0 }.collect { |element| element.to_s } # => ["2", "4", "6"]
上面代碼實現選取數組中的偶數,並把它們轉換成字元型。用inject如何?呢?
Ruby代碼
- array = [1, 2, 3, 4, 5, 6].inject([]) do |result, element|
- result << element.to_s if element % 2 == 0
- result
- end
-
- array # => ["2", "4", "6"]
是不是更直觀?