输出与地图和每个的差异

the*_*yst 2 ruby each map

我需要帮助找出为什么地图和下面的代码中的每个都有差异.

j = "This is an awesome string"

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

返回:

["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"]
Run Code Online (Sandbox Code Playgroud)

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

收益:

["U", "i", "j", "t", " ", "j", "t", " ", "b", "o", " ", "b", "x", "f", "t", "p", "n", "f", " ", "t", "u", "s", "j", "o", "h"]
Run Code Online (Sandbox Code Playgroud)

为什么改变mapeach删除零?

Aru*_*hit 5

因为Array#each返回接收器本身.但是Array#map,使用当前计算结果传递给块的每个当前字符的映射.

#map,条件if char =~ /[A-Za-z]/evalutated作为falsy,对于像每个传递元件" ".因此,nil在它找到的块映射" "或任何被if评估为错误的条件的元素.但是#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
Run Code Online (Sandbox Code Playgroud)

更新

@asquirrel的评论中,我有了一个主意.您可以用Ruby方式编写代码: -

"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"]
Run Code Online (Sandbox Code Playgroud)

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"]
Run Code Online (Sandbox Code Playgroud)