Ruby地图和紧凑的方法

时间:2016-07-26 01:10:29

标签: arrays ruby iterator

给定一个数字n,我想返回它的阶乘(1*2*3...*n)。但只有1n之间的偶数。

这是我现在的工作代码。

def fact_even(n)
  arr = (1..n).map {|m| m if m % 2 == 0}
  new_arr = arr.compact
  new_arr.inject(&:*)
end

给定块时,map返回一个新数组:

[nil, 2, nil, 4, nil, 6]

之后我必须使用compact方法摆脱nil s,然后使用inject来获得阶乘的答案。

有没有办法让map返回一个只包含偶数的数组,这样我就不必在下一行使用compact了?否则,是否有更有效的方法?

3 个答案:

答案 0 :(得分:1)

尝试使用select

> (1..20).select { |r| r % 2 == 0}
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

此外,您可以尝试将reduce用于下一行:

> (1..20).select { |r| r % 2 == 0 }.reduce(:*)
=> 3715891200

答案 1 :(得分:0)

您可以使用even?代替r % 2 == 0

n = 20
(1..n).select { |r| r.even? }.reduce(:*)
# Output: => 3715891200

请注意,injectreduce都指向相同的方法。

Range.instance_method(:inject) == Range.instance_method(:reduce)
# Output: => true

答案 2 :(得分:0)

Ruby 2.7添加了Enumerable#filter_map,这样,如果您使用的版本大于或等于2.7,则可以执行以下操作:

(1..n).filter_map {|m| m if m % 2 == 0}