我正在用Ruby创建一个箱线图生成器,并且需要计算一些东西。
假设我有这个数组:
arr = [1, 5, 7, 2, 53, 65, 24]
如何从上述数组中找到最小值(1)、最大值(65)、总计(157)、平均值(22.43)和中位数(7)?
谢谢。
lowest = arr.min
highest = arr.max
total = arr.inject(:+)
len = arr.length
average = total.to_f / len # to_f so we don't get an integer result
sorted = arr.sort
median = len % 2 == 1 ? sorted[len/2] : (sorted[len/2 - 1] + sorted[len/2]).to_f / 2
arr.length
可以被 2 整除,你需要更加小心地处理中位数。一个始终有效的方法是 do sortedarr = arr.sort ; medpt1 = arr.length / 2 ; medpt2 = (arr.length+1)/2 ; (sortedarr[medpt1] + sortedarr[medpt2]).to_f / 2 ; end
,但显然这个方法更为耗费资源,也没有你在答案中给出的那么简洁明了。 - Aidan Cullyarr.inject(:+)
并不会调用Symbol#to_proc
,当给定一个符号时,inject会直接调用rb_funcall
(这比传递一个块要快很多(或者更糟的是使用Symbol#to_proc
))。但你是对的,这只在1.8.7+版本中有效。 - sepp2k查找最小值、最大值、总和和平均值很简单,可以像sepp2k的答案中所示那样轻松地以线性时间完成。
但是查找中位数就不那么简单了。天真的实现方法(排序,然后取中间元素)需要O(nlogn)的时间。
然而,有一些算法可以在线性时间内找到中位数(如中值-5算法)。其他算法甚至适用于任何种类的顺序统计量(比如,你想要找到第五小的元素)。其中的问题是,你必须自己实现它们,我不知道Ruby是否有这样的实现。
O(nlogn)已经相当快了,因此如果你不打算处理海量数据集(如果你需要对数据进行排序),那么这种方法就足够了。