我有這樣的代碼紅寶石注入創建陣列
notebooks.inject([]) do |res, nb|
res << nb.guid if Recipe::NOTEBOOKS.include?(nb.name)
end
第一nb
具有相匹配的條件和res
看起來像這樣
["xxx1234"]
第二nb
不符合條件,然後刪除/清除res
nil
從我的理解,第一個值應該保留在數組中。
我也將此分配給一個變量,並希望它是一個班輪。
我有這樣的代碼紅寶石注入創建陣列
notebooks.inject([]) do |res, nb|
res << nb.guid if Recipe::NOTEBOOKS.include?(nb.name)
end
第一nb
具有相匹配的條件和res
看起來像這樣
["xxx1234"]
第二nb
不符合條件,然後刪除/清除res
nil
從我的理解,第一個值應該保留在數組中。
我也將此分配給一個變量,並希望它是一個班輪。
inject
工作從你如何想象有點不同。它只是返回循環的最後一個返回值,因爲它循環遍歷每個項目。一個簡單的方法來解決這個是:
notebooks.inject([]) do |res, nb|
res << nb.guid if Recipe::NOTEBOOKS.include?(nb.name)
res # Returns the res array
end
這就是說,你應該使用select
您的使用情況下,你似乎只是過濾下來,其設置的筆記本電腦你想..這就是:
notebooks.select{|nb| Recipe::NOTEBOOKS.include?(nb.name)}.map(&:guid)
一般來說,我用inject
當我需要在一組項目上運行數學。例如
[1,2,3,4].inject(0) {|res, x| x * 2 + res}
累加器必須在每個循環迭代返回:
notebooks.inject([]) do |res, nb|
Recipe::NOTEBOOKS.include?(nb.name) ? res << nb.guid : res
end
事實上,在以後每次循環迭代,傳遞給res
塊參數累加器是正是從以前的迭代返回。不執行
在你的榜樣,在第二次迭代if
回報false
和
res << nb.guid if Recipe::NOTEBOOKS.include?(nb.name)
線在所有。也就是說,在第二次迭代之後,累加器會獲得一個全新的值,這顯然是nil
。
如果你打開兩個循環,但更清潔,還是一個班輪:
notebooks.select { |nb| Recipe::NOTEBOOKS.include?(nb.name) }.map(&:guid)
+1正是我在想什麼。這也有助於可讀性,因爲您將問題分爲兩個不同的步驟。儘管如此,我至少將它分成兩行。 – Kelvin