繁体   English   中英

为什么Ruby .map无法与if语句一起使用

[英]Why Ruby .map doesn't work with if statement

我在.map使用if获得了意外的结果:

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语句的返回值。

谢谢!

对于小于4的元素, item + 10 if item < 4确实返回期望值,则item + 10 if item < 4 但是随后第二条语句执行,并且map返回值。 对于项<4, item + 9 if item > 4返回nil

您的地图应如下所示:

a.map do |item|
  if item < 4 then
      item + 10
  else
      item + 9
  end
end

如果项== 4,该怎么办?

我们可以通过将块作为方法来演示您遇到的问题:

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。

这是因为,如果使用map ,则会创建一个数组,其中包含从传递给map方法的块中求值的值。 因此,在这种情况下, item + 9 if item > 4item + 9 if item > 4在前4个元素中求值的最后一个值为item + 9 if item > 4 ,它返回nil

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]

这是关于这个主题好读物

希望对某人有用!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM