繁体   English   中英

查找最接近数组平均值的元素

[英]Find element(s) closest to average of array

做以下事情的“红宝石”方式是什么? 我仍然在考虑更多命令式的风格编程,而不是真正适应红宝石的思考。 我想要做的是找到与数组平均值最接近的元素,例如,考虑以下数组

[1,2,3] 

平均值是2.0。 我想写的方法返回最接近平均值的元素,在这种情况下是1和3。

另一个例子将更好地说明这一点

[10,20,50,33,22] avg is 27.0 method would return 22 and 33.

这不是最有效的,但它(以我的拙见)相当于Ruby风格。

class Array
  # Return the single element in the array closest to the average value
  def closest_to_average
    avg = inject(0.0,:+) / length
    min_by{ |v| (v-avg).abs }
  end
end

[1,2,3].closest_to_average
#=> 2 

[10,20,50,33,22].closest_to_average
#=> 22 

如果你真的想要n个最近的项目,那么:

class Array
  # Return a number of elements in the array closest to the average value
  def closest_to_average(results=1)
    avg = inject(0.0,:+) / length
    sort_by{ |v| (v-avg).abs }[0,results]
  end
end

[10,20,50,33,22].closest_to_average     #=> [22] 
[10,20,50,33,22].closest_to_average(2)  #=> [22, 33] 
[10,20,50,33,22].closest_to_average(3)  #=> [22, 33, 20] 

这是怎么回事

avg = inject(0.0,:+) / length
是简写:
avg = self.inject(0.0){ |sum,n| sum+n } / self.length
我从值0.0而不是0以确保总和将是一个浮点数,因此除以长度不会给我一个整数舍入值。

sort_by{ |v| (v-avg).abs }
根据数字和平均值(从最低到最高)之间的差异对数组进行排序,然后:
[0,results]
从该数组中选择第一个结果条目数。

我假设所需要的是数组中最大的元素小于平均值,并且该数组的最小值大于平均值。 当且仅当数组具有至少两个元素且它们不完全相同时,才存在这样的值。 假设条件适用,我们只需要将它从单词转换为符号:

avg = a.reduce(:+)/a.size.to_f
[ a.select { |e| e < avg }.max, a.select { |e| e > avg }.min ]

另一种方式,效率稍低:

avg = a.reduce(:+)/a.size.to_f
b = (a + [avg]).uniq.sort
i = b.index(avg)
[ b[i-1], b[i+1] ]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM