Returns the median of the numbers given
<?php function median($numbers=array()) { if (!is_array($numbers)) $numbers = func_get_args(); rsort($numbers); $mid = (count($numbers) / 2); return ($mid % 2 != 0) ? $numbers{$mid-1} : (($numbers{$mid-1}) + $numbers{$mid}) / 2; } /* echo median(array(44,12,34,21,34,55,77,54)); // 39 echo median(1,1,1,2,2,3,3,3); // 2 */ ?>
As seen in the commented portion of code, this function can take either an array of numbers, or multiple parameters of numbers. *note* returns the average median if there is an even number of numbers going in
Comments
guest
Posted on 19.04.2012 12:03
function median($numbers=array())
{
if (!is_array($numbers))
$numbers = func_get_args();
rsort($numbers);
$mid = (int)(count($numbers) / 2);
return ($mid % 2 != 0) ? $numbers[$mid] : (($numbers[$mid-1]) + $numbers[$mid]) / 2;
}
guest
Posted on 12.01.2011 21:21
Handy function, but it wasn't working correctly for me all of the time. I narrowed it down to two bugs:
1) The modulus (%) function should be applied to the original length of the array, not the length divided in half. Replacing ($mid % 2 != 0) with (count($numbers) % 2 != 0) corrects this. For example, if the original array has 30 elements, $mid will be 15. When $mid is divided by two to get the remainder with %, it will indicate that 15 is odd, when you need it to indicate that 30 is even. An array with 40 elements wouldn't show symptoms, since 20 is still even. The bug, when triggered, causes the wrong operation to be performed during the return statement.
2) The first option for the return statement ($numbers{$mid-1}) always (I think?) calls for an array element with a non-whole number. Original array has 5 elements. The third element should be returned, but half of 5 is 2.5, so the code returns element 1.5 when it should return element 2. Since 1.5 rounds up, this seems to work. I would recommend taking the ceiling of $mid before subtracting one just to be safe. Therefore, replace $numbers{$mid-1} with $numbers{ceil($mid-1} to correct this. Or use floor($mid) and you no longer need to subtract one.
3) Not a bug, but I would have used asort() instead of rsort() just to keep thing simpler to debug. Once the logic is correct, it should work with the array sorted either way.
Thanks for getting me most of the way there!
-Karl
guest
Posted on 20.12.2010 15:11
Doesn't this return the mode, not the median?
guest
Posted on 22.04.2010 09:47
echo median(array(44,12,34,21,34,55,77,54)); // 39
for this example....can u explain how u got 39...
because 3rd element is 34 n 4th is 21
so v add up (34 + 21)/2 = 55/2 = 27.5
Thnx !!
Add your comment