Ruby-根据总数和对象类型对数组进行排序

问题描述

我有一个数组,对象类型不同,并且如果非整数的总和乘以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]
]

由于字符串和浮点数的总和大于或等于整数的总和。

解决方法

您可以使用:

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"]]  

以此类推。