如果代码块的计算结果为false,则跳过可枚举#map上的值

时间:2013-10-31 20:05:03

标签: ruby enumerable

有没有办法使用map重构此方法? (此方法的目的是返回1和最大参数之间的素数数组)

def primes(max)
  prime_arr = []
   (1..max).each {|i| prime_arr << i if is_prime?(i)}
  prime_arr
end

is_prime?(val)返回true或false。

如果我将我的方法改为:

def primes(max)
 (1..max).map {|i| i if is_prime?(i)}
end

当代码块失败时,返回的数组的值为nil。

p primes(5)
#=> [1, 2, 3, nil, 5]

我知道我的工作原理,但是如果有更好的方法,我宁愿不申报数组并特别返回数组

3 个答案:

答案 0 :(得分:2)

Enumerable.reject(或Enumerable.select)是过滤序列的正确方法。

这些过滤器方法只查看返回值的 truthy-ness ,因此在这种情况下返回i“工作”(如{{ 1}}总是一个真正的值),返回的值实际上是被丢弃(与i不同)所以谓词看起来应该更像:

map

(请参阅&:了解后一种情况背后的魔力。)

此外,由于这涉及查找素数,Sieve of Eratosthenes可能是一个很好的读数。

答案 1 :(得分:1)

require 'Prime'
MAX = 100
p Prime.each(MAX).to_a      #=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31...
p (1..MAX).select(&:prime?) #=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31...

如果您想选择并转换,则可以使用grep

primes = ->x{x.prime?} # (new lambda syntax)
p (1..100).grep(primes){|x| x.to_s} #=> ["2", "3", "5", "7", "11", "13", "17",...

答案 2 :(得分:0)

是的......我在试图解释它时想出了一个方法,但请随时向我展示一个更好的方法!

def primes(max)
  (1..max).reject {|i| i if ! is_prime?(i)}
end