simonyoung - 8 months ago 114

Ruby Question

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

array.sort!

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

end

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?

Answer

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]
end
```

Source (Stackoverflow)