所以我正在编写一些代码来计算多段旅程中各种公共交通票选项的成本。 这归结为计算每个段(映射)的成本并将它们相加(reduce又名注入),这很简单:
total = journey.map {|segment| compute segment}.reduce(:+)
问题是,有时compute
返回nil
因为给定工单无法获得该段,然后求和运算会爆炸。 在这种情况下,我想返回该nil
,因为单个错误段意味着整个旅程无效。 目前我正在这样做:
fares = journey.map {|segment| compute segment}
total = if fares.include? nil
nil
else
fares.reduce(:+)
end
我也可以写成简洁但(恕我直言)可读性较差:
fares = journey.map {|segment| compute segment}
total = fares.reduce{|sum, n| (sum.nil? or n.nil?) ? nil : sum + n}
但一定有更好的方法,对吧...?
我能想到的第一件事是:
journey.map { |s| compute(s) }.reduce(0) do |sum, fee|
break nil unless fee
sum + fee
end
更新:一旦compute
返回nil
,这将立即返回nil
:
journey.reduce(0) do |sum, segment|
fee = compute(segment)
break nil unless fee
sum + fee
end
按以下步骤操作:
result = []
journey.take_while { |segment| !(result << compute(segment)).include?(nil) }
total = (result.size == journey.size) ? result.inject(:+) : nil
您可以使用Array#take_while
方法:
将元素传递给块,直到块返回 nil 或 false,然后停止迭代并返回所有先前元素的数组。