muppet77 Posted February 25, 2018 Share Posted February 25, 2018 with this third party code function rank($input) { $output = array(); $ranking = $input; sort($ranking); $ranking = array_flip($ranking); $last_val = -1; foreach($ranking as $key => $val){ $repetitions = ($val-$last_val-1); $last_val = $val; if($repetitions) { $ranking[$key] = (($val*($repetitions+1))-($repetitions+1)*(($repetitions)/2))/($repetitions+1)+1 ; } else { $ranking[$key] = $val+1; } } foreach($input as $key => $val){ $output[$key] = $ranking[$val]; } return $output; } $a = array(4,76,34,13,34); $c = rank($a); print_r($c); that ranks an array, how could i tweak it to rank the other way round, so the highest value = 1, etc? thanks Link to comment Share on other sites More sharing options...
requinix Posted February 25, 2018 Share Posted February 25, 2018 Without thinking too hard about it, sort($ranking);that is the only place in the code that does any kind of sorting, so to reverse the results you would reverse the sorting. Link to comment Share on other sites More sharing options...
Barand Posted February 25, 2018 Share Posted February 25, 2018 try function rank($input) { $ranked = []; arsort($input); $prev = null; $rank = $count = 0; foreach ($input as $k => $v) { ++$count; $rank = $v==$prev ? $rank : $count ; $ranked[$k] = $rank; $prev = $v; } return $ranked; } $a = array('A'=>4, 'B'=>76, 'C'=>34, 'D'=>13, 'E'=>34); $b = rank($a); #------------------------------# # output results # #------------------------------# echo '<pre>'; echo "<br>Input - with rank<br>"; foreach ($a as $k => $v) { printf('%s | %3d | %3d<br>', $k, $v, $b[$k]); } echo "<br>Order by rank<br>"; asort($b); foreach ($b as $k => $r) { printf('%s | %3d | %3d <br>', $k, $a[$k], $r); } /* giving: *********************************** Input - with rank A | 4 | 5 B | 76 | 1 C | 34 | 2 D | 13 | 4 E | 34 | 2 Order by rank B | 76 | 1 C | 34 | 2 E | 34 | 2 D | 13 | 4 A | 4 | 5 **********************************************/ Link to comment Share on other sites More sharing options...
muppet77 Posted February 25, 2018 Author Share Posted February 25, 2018 Thanks both. What’s the name of the new ranked array, Barand? Link to comment Share on other sites More sharing options...
Barand Posted February 25, 2018 Share Posted February 25, 2018 I'll give you a clue. There are two arrays ($a and $b) and $a contains the original input. $a = Array ( [A] => 4 [B] => 76 [C] => 34 [D] => 13 [E] => 34 ) $b = Array ( [B] => 1 [C] => 2 [E] => 2 [D] => 4 [A] => 5 ) Link to comment Share on other sites More sharing options...
muppet77 Posted February 25, 2018 Author Share Posted February 25, 2018 haha. thanks Barand. I've now realised that my data are non - integer numbers and so ranking doesn't quite work anymore in this way. i have an integer and i've added a random number that has about 5 decimal places - i then need to rank these non integers in the array. Is there a quick and easy fix to rank non integers? thanks Link to comment Share on other sites More sharing options...
Barand Posted February 25, 2018 Share Posted February 25, 2018 The rank() function works exactly the same with floats or integers. The only things that would change in my code are the format strings in the printf() functions so they display float values. function rank($input) { $ranked = []; arsort($input); $prev = null; $rank = $count = 0; foreach ($input as $k => $v) { ++$count; $rank = $v==$prev ? $rank : $count ; $ranked[$k] = $rank; $prev = $v; } return $ranked; } $a = array('A'=>4.12345, 'B'=>76.09871, 'C'=>34.12345, 'D'=>13.65421, 'E'=>34.12345); $b = rank($a); #------------------------------# # output results # #------------------------------# echo '<pre>'; echo "<br>Input - with rank<br>"; foreach ($a as $k => $v) { printf('%s | %8.5f | %3d<br>', $k, $v, $b[$k]); } echo "<br>Order by rank<br>"; asort($b); foreach ($b as $k => $r) { printf('%s | %8.5f | %3d <br>', $k, $a[$k], $r); } Results Input - with rank A | 4.12345 | 5 B | 76.09871 | 1 C | 34.12345 | 2 D | 13.65421 | 4 E | 34.12345 | 2 Order by rank B | 76.09871 | 1 C | 34.12345 | 2 E | 34.12345 | 2 D | 13.65421 | 4 A | 4.12345 | 5 Link to comment Share on other sites More sharing options...
muppet77 Posted February 26, 2018 Author Share Posted February 26, 2018 Cheers buddy. Appreciated. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.