为什么三元语法在这种情况下不起作用?

时间:2014-01-21 16:22:30

标签: ruby ternary-operator

这是有效的:

def prime? n
  (2...n).each {|num| return false if n % num == 0 }
  true
end

这是 NOT 有效

def prime? n
  (2...n).each {|num| n % num == 0 ? return false : true }
end

这些是不是同样的事情?为什么第二个示例会导致语法错误?

<小时/> 现在为什么下一个示例适用于ternary语法?

def primes max
  primes_arr = []
  (2...max).map { |num| prime?(num) ? primes_arr << num : next }
  primes_arr
end

3 个答案:

答案 0 :(得分:4)

该代码导致语法错误,因为 ruby​​ 解释器不知道return关键字的参数在哪里结束,正确的示例是:

def prime? n
   (2...n).each {|num| n % num == 0 ? ( return false ) : true }
end

这是next并不是真正需要只使用布尔逻辑:

def primes max
   primes_arr = []
   (2...max).map { |num| prime?(num) && primes_arr << num }
   primes_arr
end

如果我们进行一些优化,我们可以这样做:

def prime? n
   (2...n).all? {|num| n % num != 0 }
end

def primes max
   (2...max).select {|num| prime?(num) }
end

下一级优化shell是这样的:

def primes max
   (2...max).select {|num| (2...num).all? {|num1| num % num1 != 0 } }
end
primes 7
# => [2, 3, 5] 

答案 1 :(得分:3)

添加括号以明确说明Ruby解释你所拥有的方式:

(2...n).each { |num| (n % num == 0 ? return false) : true }

我们可以验证这一点,因为我们得到带括号和不带括号的相同错误消息:

  

SyntaxError:(eval):2:语法错误,意外的keyword_false,期待':'

你可以通过给出明确的括号来强制Ruby解释它你想要的方式来解决这个问题:

(2...n).each { |num| n % num == 0 ? (return false) : true }

或者您只能在满足案例时返回false(正如您在问题中所做的那样)。或者,更好的是,改为使用any?

(2...n).any? { |num| n % num != 0 }

答案 2 :(得分:2)

这是三元运算符的正确用法(根本没有运算符:))

def prime? n
  !(2...n).any? {|num| n % num == 0 }
  # or
  # (2...n).all? {|num| n % num != 0 }
end

(1..10).each do |x|
  puts "prime?(#{x}) \# => #{prime?(x)}"
end
# >> prime?(1) # => true
# >> prime?(2) # => true
# >> prime?(3) # => true
# >> prime?(4) # => false
# >> prime?(5) # => true
# >> prime?(6) # => false
# >> prime?(7) # => true
# >> prime?(8) # => false
# >> prime?(9) # => false
# >> prime?(10) # => false