在 Ruby 中计算中位数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14859120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calculating Median in Ruby
提问by tomgalpin
How do I calculate the median of an array of numbers using Ruby?
如何使用 Ruby 计算一组数字的中位数?
I am a beginner and within the progress of my learning I am trying to stick to what has already been taught. Thus the other questions that I've found are beyond my scope.
我是一个初学者,在我学习的过程中,我试图坚持已经教过的东西。因此,我发现的其他问题超出了我的范围。
Here are my notes and my attempt:
这是我的笔记和我的尝试:
- sort the array in ascending order.
- figure out if it is odd or even in length.
- if odd, divide the sorted array length +1 in half. That is the index of the median. Return this value.
- if even, find the middle two numbers of the sorted array and divide them in 1/2. Return this value.
- Finding the middle two numbers:
- divide the sorted array length in half. This is index pt. first middle number.
- divide sorted array length + 2 in half. This is the index pt. of the second middle number.
take average of these two middle numbers.
def median(array) ascend = array.sort if ascend % 2 != 0 (ascend.length + 1) / 2.0 else ((ascend.length/2.0) + ((ascend.length + 2)/2.0) / 2.0) end end
- 按升序对数组进行排序。
- 弄清楚它的长度是奇数还是偶数。
- 如果是奇数,则将排序后的数组长度 +1 一分为二。那是中位数的指数。返回这个值。
- 如果偶数,则找到已排序数组的中间两个数字并将它们除以 1/2。返回这个值。
- 找到中间的两个数字:
- 将排序后的数组长度一分为二。这是索引 pt。第一个中间数字。
- 将排序后的数组长度 + 2 分成两半。这是索引pt。第二个中间数字。
取这两个中间数字的平均值。
def median(array) ascend = array.sort if ascend % 2 != 0 (ascend.length + 1) / 2.0 else ((ascend.length/2.0) + ((ascend.length + 2)/2.0) / 2.0) end end
回答by nbarraille
Here is a solution that works on both even and odd length array and won't alter the array:
这是一个适用于偶数和奇数长度数组并且不会改变数组的解决方案:
def median(array)
sorted = array.sort
len = sorted.length
(sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0
end
回答by AnkitG
回答by Kal
Similar to nbarraille's, but I find it a bit easier to keep track of why this one works:
与 nbarraille 类似,但我发现跟踪它为什么有效更容易一些:
class Array
def median
sorted = self.sort
half_len = (sorted.length / 2.0).ceil
(sorted[half_len-1] + sorted[-half_len]) / 2.0
end
end
half_len = number of elements up to and including (for array with odd number of items) middle of array.
half_len = 直到并包括(对于具有奇数个项目的数组)数组中间的元素数。
Even simpler:
更简单:
class Array
def median
sorted = self.sort
mid = (sorted.length - 1) / 2.0
(sorted[mid.floor] + sorted[mid.ceil]) / 2.0
end
end
回答by Kyle Snow Schwartz
def median(array) #Define your method accepting an array as an argument.
array = array.sort #sort the array from least to greatest
if array.length.odd? #is the length of the array odd?
array[(array.length - 1) / 2] #find value at this index
else array.length.even? #is the length of the array even?
(array[array.length/2] + array[array.length/2 - 1])/2.to_f
#average the values found at these two indexes and convert to float
end
end
回答by Alexander
More correct solution with handling edge cases:
处理边缘情况的更正确的解决方案:
class Array
def median
sorted = self.sort
size = sorted.size
center = size / 2
if size == 0
nil
elsif size.even?
(sorted[center - 1] + sorted[center]) / 2.0
else
sorted[center]
end
end
end
There is a specs to prove:
有一个规范可以证明:
describe Array do
describe '#median' do
subject { arr.median }
context 'on empty array' do
let(:arr) { [] }
it { is_expected.to eq nil }
end
context 'on 1-element array' do
let(:arr) { [5] }
it { is_expected.to eq 5 }
end
context 'on 2-elements array' do
let(:arr) { [1, 2] }
it { is_expected.to eq 1.5 }
end
context 'on odd-size array' do
let(:arr) { [100, 5, 2, 12, 1] }
it { is_expected.to eq 5 }
end
context 'on even-size array' do
let(:arr) { [7, 100, 5, 2, 12, 1] }
it { is_expected.to eq 6 }
end
end
end
回答by Zoh
def median(arr)
sorted = arr.sort
if sorted == []
return nil
end
if sorted.length % 2 != 0
result = sorted.length / 2 # 7/2 = 3.5 (rounded to 3)
return sorted[result] # 6
end
if sorted.length % 2 == 0
result = (sorted.length / 2) - 1
return (sorted[result] + sorted[result+1]) / 2.0 # (4 + 5) / 2
end
end
p median([5, 0, 2, 6, 11, 10, 9])
回答by Nana
Here's a solution:
这是一个解决方案:
app_arry = [2, 3, 4, 2, 5, 6, 16].sort
# check array isn't empty
if app_arry.empty? || app_arry == ""
puts "Sorry, This will not work."
return nil
end
length = app_arry.length
puts "Array length = #{length}"
puts "Array = #{app_arry}"
if length % 2 == 0
# even number of elements
puts "median is #{(app_arry[length/2].to_f + app_arry[(length-1)/2].to_f)/2}"
else
# odd number of elements
puts "median is #{app_arry[(length-1)/2]}"
end
OUTPUT
输出
Array length = 7
Array = [2, 3, 4, 2, 5, 6, 16]
median is 2
数组长度 = 7
数组 = [2, 3, 4, 2, 5, 6, 16]
中位数是 2
回答by Yashvi Patel
def median(array, already_sorted=false)
return nil if array.empty?
array = array.sort unless already_sorted
m_pos = array.size / 2
return array.size % 2 == 1 ? array[m_pos] : mean(array[m_pos-1..m_pos])
end
回答by user3007294
def median(array)
half = array.sort!.length / 2
array.length.odd? ? array[half] : (array[half] + array[half - 1]) / 2
end
*If the length is even, you must add the middle point plus the middle point - 1 to account for the index starting at 0
*如果长度为偶数,则必须加上中点加上中点-1来占索引从0开始
回答by whatzzz
I think it's good:
我觉得很好:
#!/usr/bin/env ruby
#in-the-middle value when odd or
#first of second half when even.
def median(ary)
middle = ary.size/2
sorted = ary.sort_by{ |a| a }
sorted[middle]
end
or
或者
#in-the-middle value when odd or
#average of 2 middle when even.
def median(ary)
middle = ary.size/2
sorted = ary.sort_by{ |a| a }
ary.size.odd? ? sorted[middle] : (sorted[middle]+sorted[middle-1])/2.0
end
I used sort_by rather than sort because it's faster: Sorting an array in descending order in Ruby.
我使用 sort_by 而不是 sort 因为它更快:在 Ruby 中按降序对数组进行排序。

