我正在学习Ruby2.3,我尝试实现一个对输入字符串执行卢恩信用卡验证算法的函数,如果匹配,返回true,如果不匹配,返回false。
def luhn(card_no)
card_no.split("") # Break into individual digits
.reverse # Start from the end
.each_with_index
.map {|x, i| i.odd? and x.to_i * 2 or x.to_i} # Double every other digit
.map {|x| if x.to_s.length > 1; x.to_s.split("").map(&:to_i).inject(:+); else x end} # If any numbers are now 2-digit, add their digits
.inject(:+) % 10 == 0 # Check if multiple of 10
end
p luhn("4070590981311") # => true
p luhn("3103138183910") # => false有没有办法让这段代码更短或者更像“Ruby”?我确信一定有更好的方法来执行第二个map操作。
发布于 2016-07-11 06:00:47
作为对另一个答案的一个小改进,您可以通过使用double对数字进行拆分来避免声明一个.divmod变量,如下所示:
def luhn card_no
return false if card_no.empty?
card_no.chars.reverse.each_slice(2).flat_map do |a, b|
[a.to_i, *(b.to_i * 2).divmod(10)]
end.inject(:+) % 10 == 0
end这样它就会稍微紧凑一些。
另外,我们现在需要.flat_map (而不是.map),因为我们从块返回数组,而不是标量。
https://codereview.stackexchange.com/questions/134439
复制相似问题