2016-08-25 47 views
5

我無法理解mapeach之間的區別以及何時何地使用它們。如何理解Ruby的.each和.map

我看了「What does map do?」和「Ruby Iterators」,但想要澄清一下。

如果我有:

z = [1,2,3].map {|x| x + 1} 

map需要每個元素的數組z並添加一個到每個元素,但是除非我添加!它不發生變異原數組。

在另一方面:

y = [1,2,3].each {|x| x + 1} 

回報[1,2,3]。這是令人困惑我,因爲:

names = ['danil', 'edmund'] 
names.each { |name| puts name + ' is a programmer' } 

回報:

Danil is a programmer 
Edmund is a programmer 

究竟是什麼事情在我未允許每個數組元素將增加1秒例如,儘管在過去的例如一個字符串正在附加到數組中的所有內容?

所有學分都歸斯佩蘭斯基達尼爾所有,我將這些例子從中取消。

+3

「返回 達尼爾是一個程序員」 - 不。你很困惑。這不是返回值。這是塊的__side-effect__(它打印到標準輸出)。 '.each'的返回值仍然是原始的可枚舉值(在這兩行後面看到) –

回答

3

map方法需要enum給定一些塊,並通過它循環做一些邏輯。在你的情況下,邏輯是x+1。正如你所說,除非你使用!,否則它不會改變任何東西。

each只是返回被調用的數組。

讓我們的例子:

names = ["bob"] 

如果我們這樣做:

names.each{|names| names + "somestring"} 

輸出仍然["bob"]。你的第二個例子不同的原因是由於puts

作爲練習嘗試做:

y = [1,2,3].each {|x| puts x + 1} 

您將獲得:

2 
3 
4 
[1,2,3] 
0

在第一種情況,map

z = [1,2,3].map {|x| x + 1} 

將採取給定的陣列中的每個元素和在塊執行操作,並返回一個新的數組,所以在這裏它返回[2,3,4]

.each爲數組中的每個元素執行塊,並且它不會更改數組中的任何內容,因此它在此處執行x + 1,但它不會將其存儲在任何位置,因此在第二種情況下它只返回陣列。

現在在您發佈的第三個示例中,您將在塊本身中打印輸出。同樣,數組本身沒有變化。

+0

請小心使用粗體文本。這是相當於黃色的所有帽子,這是視覺嘈雜。有幾次大膽的是適當的,所以非常謹慎地使用它。想象一本像百科全書這樣的參考書,你多久見一次粗體文字? –

0

區別在於each正在對數組中的每個元素執行操作,返回原始數組。執行的操作可能會使元素髮生變化。

map正在對數組中的每個元素執行操作並將其結果作爲數組返回。

3

TL;博士:我用map如果我想改變我的收藏,就可以應用轉換,結束與一些不同的東西。如果我只需要訪問集合中的每個元素,我就使用each

要點是:如果您想對數組應用轉換(實際上可枚舉,但讓我們在開始時保持簡單),則應使用map。否則,如果您不需要更改陣列,則可以簡單地使用each

請注意,在下面的代碼中,您不會突變數組,但您只是利用本地字符串來打印帶有後綴的每個字符串。

names = ['danil', 'edmund'] 
names.each { |name| puts name + ' is a programmer' } 

很明顯,你可以做同樣的map但在這種情況下,你不需要它,你必須給每個使用過打印的每一個元素。該代碼將是

names = ['danil', 'edmund'] 
names.map! { |name| name + ' is a programmer' } 
# or names = names.map { |name| name + ' is a programmer' } 
name.each { |name| puts name } 
1

這是覆蓋Ruby的在多個地方的文件中,但最容易理解你的用途是用於each陣列文檔中:

each { |item| block } → ary 
each → Enumerator 

調用給定塊一次對於self中的每個元素,將該元素作爲參數傳遞。返回數組本身。

如果未指定塊,則返回枚舉器。

a = [ "a", "b", "c" ] 
a.each {|x| print x, " -- " } 

生產: 「返回數組本身

a -- b -- c -- 

注意,它說

與此相比,map

map { |item| block } → new_ary 
map → Enumerator 

爲每個自我元素調用一次給定的塊。

創建一個包含塊返回的值的新數組。

另請參閱Enumerable#collect。

如果沒有指定塊,則返回一個枚舉器。

a = [ "a", "b", "c", "d" ] 
a.collect { |x| x + "!" }   #=> ["a!", "b!", "c!", "d!"] 
a.map.with_index { |x, i| x * i } #=> ["", "b", "cc", "ddd"] 
a         #=> ["a", "b", "c", "d"] 

注意,它說: 「創建包含由塊返回的值的新數組。」

本示例將幫助瞭解以上:

foo = [1,2,3] 
foo.each { |i| puts i + 1 } # => [1, 2, 3] 
foo.map { |i| i + 1 } # => [2, 3, 4] 

# >> 2 
# >> 3 
# >> 4 

其中# =>是塊的返回值,並且# >>是從puts獲取的STDOUT。

而且,知道所有這一切,當您想要顯示數組中的元素或提取並重用這些元素作爲參數或構建事物時,請使用each。當您想要將數組的元素更改爲其他內容時,請使用map