Personally this is the way that I would build the function:
function calculateMedian($Values)
{
//Remove array items less than 1
$Values = array_filter($Values,array($this,"callback"));
//Sort the array into descending order 1 - ?
sort($Values, SORT_NUMERIC);
//Find out the total amount of elements in the array
$Count = count($Values);
//Check the amount of remainders to calculate odd/even
if($Count % 2 == 0)
{
return $Values[$Count / 2];
}
return (($Values[($Count / 2)] + $Values[($Count / 2) - 1]) / 2);
}
What changes have I made?
I have used less variables, overwriting the $Values
where needed
Reduced the conditional statements to 1* from 2
Made the code look more readable and understandable.
I have however added a callback, which in turn removes the foreach
and if
statements but a logical check would have to be used in the callback.Tthe callback would simply be a method in your class like so:
public function callback($value)
{
return $value > 0;
}
Unfortunately as the native function empty
is actually a language construct it's not a valid callback; you can however use return !empty($value);
within your callback method to also remove other entities such as NULL
,FALSE
etc.
This can be removed as stated, and placed outside the function.
*Notes: I would advise you to have some kind of linear array check to make sure the arrays are based on an integer index, as our code assumes they are, a linear check can be done like so:
if(array_keys($Values) !== range(0,($Count-1)))
{
return null;
}
This would be added after the $Count
value has come into play.
Example test that I had used to test it was:
$values = array(
0,4,7,5,6,9,5,3,2,7,5,6,4,3,7
);
echo calculateMedian($values);
which resulted in the correct answer of 5.
$iCount
in 1st iteration should be$count
. \$\endgroup\$