输出与地图和每个的差异

时间:2014-07-09 07:11:43

标签: ruby map each

我需要帮助找出地图与以下代码中每个地图之间存在差异的原因。

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的更改会删除nil?

1 个答案:

答案 0 :(得分:5)

因为Array#each会返回接收器本身。但Array#map maps ,每个当前字符,您传递给块,并带有当前计算结果。

使用#map,条件if char =~ /[A-Za-z]/评估为 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的评论中,我有了一个主意。您可以用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"]

<强> 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"]