我目前正在学习红宝石并玩弄收藏品。我现在陷入了一个问题,需要一些帮助来理解为什么有些东西会这样运作。
所以,我们有一个简单的数组:
arr = ["cat", "dog", "pig", "goat"]
现在,我想让每一个元素上升并反转。我认为的第一件事就是三元:
modified = arr.each_with_index.map do |el, idx|
((idx + 1) % 2 == 0) ? el.upcase.reverse : el
end
没什么大不了的。但我玩了一遍,想出了另一个解决方案。
modified = arr.each_with_index.map do |el, idx|
el.upcase.reverse if (idx + 1) % 2 == 0
el unless (idx + 1) % 2 == 0
end
这对我来说似乎是正确的,但不是对翻译来说。
通过三元组我得到了结果:
["cat", "GOD", "pig", "TAOG"]
但是采用后一种方法:
["cat", nil, "pig", nil]
有人可以解释为什么后者不起作用(它会在每一秒钟上放置一次)吗?
如果我使用常规的if-else,它会再次起作用。
modified = arr.each_with_index.map do |el, idx|
if (idx + 1) % 2 == 0
el.upcase.reverse
else
el
end
end
常规if如何与one-liners不同?
提前致谢!
答案 0 :(得分:2)
Array#map
将使用参数中传递的块的返回值来构建新数组。
由于您没有使用任何return
语句,因此它始终是最后评估的表达式。
在您的第一个和第三个解决方案中,您始终“点击”el
或el.upcase.reverse
在您的第二个解决方案中,当(idx + 1) % 2 == 0
时,您没有做任何事情,因此您只需返回nil
。
希望这有帮助。
注意:查看Integer#odd?
和Integer#even?
答案 1 :(得分:1)
下面
modified = arr.each_with_index.map do |el, idx|
el.upcase.reverse if (idx + 1) % 2 == 0
el unless (idx + 1) % 2 == 0
end
如果条件满足,则此行el unless (idx + 1) % 2 == 0 #=> nil
。数组["cat", nil, "pig", nil]
如下。
arr.map.with_index { |str,i| i.odd? ? str.upcase.reverse : str }
#=> ["cat", "GOD", "pig", "TAOG"]