似乎有很多方法可以循環遍歷Ruby中的Enumerable。 each
,foreach
或collect
,map
或其他類似方法之間是否有區別?「each」,「foreach」,「collect」和「map」之間有什麼區別?
或者是否有一個原因,我不應該在某些情況下使用某些方法?
似乎有很多方法可以循環遍歷Ruby中的Enumerable。 each
,foreach
或collect
,map
或其他類似方法之間是否有區別?「each」,「foreach」,「collect」和「map」之間有什麼區別?
或者是否有一個原因,我不應該在某些情況下使用某些方法?
collect
/map
是等效的。它們與each
不同,因爲each
只對每個元素執行塊,而collect
/map
返回一個數組,其結果爲每個元素調用塊。把它可能是另一種方式,each
預計做東西。每一個元素,而map
預計變換每個元素(它映射到別的東西)。
你可以使用collect
或map
任何地方each
使用,您的代碼仍然可以工作。但是它的效率可能會稍微低一些,因爲它會將結果收集到一個數組中,除非您的Ruby實現意識到它不必費心創建一個數組,因爲它從未被使用過。
另一個原因是使用each
,而不是map
或collect
是,以幫助任何人閱讀你的代碼。如果我看到each
,那麼我可以很好,我們即將使用數據的每個元素來做一些事情。如果我看到map
,那麼我期望根據舊數據的重新映射來查看正在創建的新數據。
關於map
與collect
我會說這是一個偏好問題,但您應該選擇一個並堅持一致。
Array#collect
(和Array#map
)根據塊中傳遞的代碼返回一個新數組。 Array#each
對數組的每個元素執行操作(由塊定義)。
我會用collect
這樣的:
array = [1, 2, 3]
array2 = array.collect {|val| val + 1}
array.inspect # => "[1, 2, 3]"
array2.inspect # => "[2, 3, 4]"
而且each
這樣的:
array = [1, 2, 3]
array.each {|val| puts val + 1 }
# >> 2
# >> 3
# >> 4
array.inspect # => "[1, 2, 3]"
使用pry
和Rubinus
(它更易於閱讀Ruby代碼),看看自己
$ pry
[1] pry(main)> cd Enumerable
[2] pry(Enumerable):1> show-method collect
From: .../rbx-head/kernel/common/enumerable18.rb @ line 4:
Owner: Enumerable
Visibility: public
Number of lines: 9
def collect
if block_given?
ary = []
each { |o| ary << yield(o) }
ary
else
to_a
end
end
[3] pry(Enumerable):1> show-method map
From: .../rbx-head/kernel/common/enumerable18.rb @ line 4:
Owner: Enumerable
Visibility: public
Number of lines: 9
def collect
if block_given?
ary = []
each { |o| ary << yield(o) }
ary
else
to_a
end
end
[4] pry(Enumerable):1>
所以不適合這些兩項。
map
和collect
迭代集合。對於每個對象它執行你的塊然後收集結果。 each
方法不收集結果
「'each''預計會對每個元素做某事,而'map'預計會對每個元素進行轉換。」不轉換也是一種做法嗎?區別不在於做什麼,而在於回報。 – SasQ 2013-08-23 06:17:29