simonyoung simonyoung - 19 days ago 4x
Ruby Question

Ruby on Rails method to calculate percentiles - can it be refactored?

I have written a method to calculate a given percentile for a set of numbers for use in an application I am building. Typically the user needs to know the 25th percentile of a given set of numbers and the 75th percentile.

My method is as follows:

def calculate_percentile(array,percentile)
#get number of items in array
return nil if array.empty?

#sort the array

#get the array length
arr_length = array.length

#multiply items in the array by the required percentile (e.g. 0.75 for 75th percentile)
#round the result up to the next whole number
#then subtract one to get the array item we need to return
arr_item = ((array.length * percentile).ceil)-1

#return the matching number from the array
return array[arr_item]


This looks to provide the results I was expecting but can anybody refactor this or offer an improved method to return specific percentiles for a set of numbers?


Some remarks:

  • If a particular index of an Array does not exist, [] will return nil, so your initial check for an empty Array is unnecessary.
  • You should not sort! the Array argument, because you are affecting the order of the items in the Array in the code that called your method. Use sort (without !) instead.
  • You don't actually use arr_length after assignment.
  • A return statement on the last line is unnecessary in Ruby.
  • There is no standard definition for the percentile function (there can be a lot of subtleties with rounding), so I'll just assume that how you implemented it is how you want it to behave. Therefore I can't really comment on the logic.

That said, the function that you wrote can be written much more tersely while still being readable.

def calculate_percentile(array, percentile)
  array.sort[(percentile * array.length).ceil - 1]