2014-07-09 25 views
2

我需要幫助找出爲什麼地圖和我的下面的代碼之間有差異。與地圖和每個輸出的差異

j = "This is an awesome string" 

j.split('').map do |char| 
    char.next! if char =~ /[A-Za-z]/ 
end 

這將返回:

["U", "i", "j", "t", nil, "j", "t", nil, "b", "o", nil, "b", "x", "f", "t", "p", "n", "f", nil, "t", "u", "s", "j", "o", "h"] 

j.split('').each do |char| 
    char.next! if char =~ /[A-Za-z]/ 

回報:

["U", "i", "j", "t", " ", "j", "t", " ", "b", "o", " ", "b", "x", "f", "t", "p", "n", "f", " ", "t", "u", "s", "j", "o", "h"] 

爲什麼從mapeach的變化除去零?

+0

像往常一樣,有一個oneliner這在紅寶石:' 「這是一個真棒字符串」 .gsub(/ [Az] /){| c | c.next}'與問題沒有嚴格的相關性,但值得了解(我認爲無論如何)。 – amnn

+1

@asQuirreL在你的路上......''這是一個很棒的字符串「.enum_for(:gsub,/[a-z]/i).map(&:next)'......希望你會喜歡。它實際上是#map,它會在迭代期間告訴你它做了什麼。:-) –

+0

類似的,有'這是一個很棒的字符串'.gsub(/ [Az] /,&::next)'(你的解決方案的問題是它實際上刪除了非字母字符,而不是忽略它們)。 – amnn

回答

5

因爲Array#each返回接收器本身。但是Array#map,映射爲,您將當前計算結果傳遞給塊的每個當前字符。

隨着#map,條件if char =~ /[A-Za-z]/ evalutated如falsy,對於像" "每個傳遞元件。因此,塊映射nil,同時它找到" "if條件評估爲falsy的任何元素。但#each在每個迭代完成後忘記了塊結果,但#map沒有。

如果你看看輸出,你可以看到所有的nil(s)在" "的相同位置。這一觀察結果也說明了我剛纔提到的行爲。

在Ruby中,每個代碼塊,如類的定義,方法定義,塊定義都會返回其最後一條語句。在您的#map區塊中,if modifier之後沒有任何聲明,因此它會重播nil

在Ruby> = 2.1.1中,我看到了方法將其名稱作爲符號返回。但是當你調用它時,它會返回最後一個語句。如果方法體是空的,則nil。下面

看: -

[1] pry(main)> def foo 
[1] pry(main)* end 
=> :foo 
[2] pry(main)> foo 
=> nil 
[3] pry(main)> def baz 
[3] pry(main)* 12 
[3] pry(main)* end 
=> :baz 
[4] pry(main)> baz 
=> 12 

更新

@asquirrel的評論,我有一個想法。你可以寫你的代碼更紅寶石方式: -

"This is an awesome string".gsub(/[a-z]/i).map(&:next) 
# => ["U", "i", "j", "t", "j", "t", "b", "o", "b", 
# "x", "f", "t", "p", "n", "f", "t", "u", "s", "j", "o", "h"] 

UPDATE1

j = "This is an awesome string" 

array = j.split('').map do |char| 
    char =~ /[A-Za-z]/ ? char.next : char 
end 

p array 

# >> ["U", "i", "j", "t", " ", "j", "t", " ", "b", "o", " ", "b", 
# "x", "f", "t", "p", "n", "f", " ", "t", "u", "s", "j", "o", "h"] 
+0

如果我不希望它替換空間而忽略並離開它,該怎麼辦? – theamateurdataanalyst

+0

@ user2801122查看更新 –

+0

so我的更新阻止了新代碼保持乾淨的一行? – theamateurdataanalyst