我在if
内使用.map
时收到了意外的结果:
a = [1,2,3,4,5]
a.map do |item|
item + 10 if item < 4
item + 9 if item > 4
end
我期待:[11,12,13,13,14]
......但我得到了:[nil, nil, nil, nil, 14]
为什么?
其次,我知道最后一个表达式是方法的返回值 if语句也是如此吗?最后一个表达式是if语句的返回值。
谢谢!
答案 0 :(得分:1)
对于&lt; 4,item + 10 if item < 4
确实返回了预期值。但随后第二个语句执行,map返回那个值。对于项目&lt; 4,item + 9 if item > 4
返回nil
。
您的地图应该是这样的:
a.map do |item|
if item < 4 then
item + 10
else
item + 9
end
end
如果项目== 4,你会怎么做?
答案 1 :(得分:1)
我们可以通过将块写为方法来证明您遇到的问题:
def test_map(item)
item + 10 if item < 4
item + 9 if item > 4
end
test_map 3
# => nil
test_map 5
# => 14
这里发生了什么?对于item=3
,第一行返回13
,但这不是从方法返回的内容 - 该方法继续到下一行,评估为nil
...
为了根据多个条件返回单个值,您可以使用if..elsif..else
构造或case..when
构造:
def test_map2(item)
case item
when 0..4
item + 10
when 4..10
item + 9
else
item
end
end
test_map2 3
# => 13
test_map2 5
# => 14
case..when
返回第一个 when
子句之后的块,该子句被评估为true。
答案 2 :(得分:1)
Ruby 2.7 +
现在有解决方案!
Ruby 2.7为此引入了filter_map
。它是惯用语言和高性能,我希望它很快会成为常态。
例如:
numbers = [1, 2, 5, 8, 10, 13]
enum.filter_map { |i| i * 2 if i.even? }
# => [4, 16, 20]
希望对某人有用!
答案 3 :(得分:0)
这是因为如果您使用map
,则创建包含从传递到map
方法的块计算的值的数组。因此,在这种情况下,前4个元素中评估的最后一个值是item + 9 if item > 4
,它返回nil
。