问题描述
我有一个数组,对象类型不同,并且如果非整数的总和乘以2大于或等于整个数组的总和,我希望从数组的数组中提取数组。例如:
elements = [
[1,2,"3","4"],[1,"2",5],["1",3,"4.0"],4,"5"],3.0,4.0,5.0]
]
expected output:
elements = [
[1,5.0]
]
由于字符串和浮点数的总和大于或等于整数的总和。
解决方法
您可以使用:
-
Array#select
根据条件提取数组 -
Enumerable#grep_v
提取非整数 -
Array#sum
计算总和(使用to_f
进行转换)
elements.select do |ary|
ary.grep_v(Integer).sum(&:to_f) * 2 >= ary.sum(&:to_f)
end
#=> [[1,2,"3","4"],["1",3,"4.0"],[1,3.0,4.0,5.0]]
您也可以将to_f
呼叫传递给grep_v
,即ary.grep_v(Integer,&:to_f).sum
,但我希望双方都进行相同的sum
呼叫。
创建一个lambda来乘以被调用的对象。我们需要将字符串转换为浮点数,因为字符串可以表示整数或浮点数。
multiply = -> (x) {
x = x.to_f if x.is_a? String
x * 2 # both lines could of course be re-written at x.to_f * 2 as engineersmnky suggests,this was a verbose way of explaining the need to convert to float
}
反向grep整数对象,返回任何其他类型并将它们乘以与映射到float的数组进行交叉比较(以处理多种类型)。
elements.select { |arr| arr.grep_v(Integer,&multiply).sum >= arr.map(&:to_f).reduce(:+) }
,
elements.select do |a|
ints,non_ints = a.partition { |e| e.is_a? Integer }
non_ints.sum(&:to_f) >= ints.sum
end
#=> [[1,5.0]]
请参见Enumerable#partition。注意:
a = elements[0]
#=> [1,"4"]
ints,non_ints = a.partition { |e| e.is_a? Integer }
#=> [[1,2],["3","4"]]
a = elements[1]
# => [1,"2",5]
ints,5],["2","3"]]
以此类推。