Kiran Kumar
Kiran Kumar

Reputation: 179

Ranking/Position on value of array in PHP

I have an array with these values, Array ( [0] => 12 [1] => 17 [2] => 5 [3] => 27 [4] => 5 ) and I need to find out ranking/position of each value ie,

for 27 - Rank 1 
for 17 - Rank 2 
for 12 - Rank 3 
for 5 - Rank 4 
for 5 - Rank 4 (duplicate value in the array) 

and these need to be in the same order as the array, so that output should be as follow

12 - Rank 3 
17 - Rank 2 
5 - Rank 4 
27 - Rank 1 
5 - Rank 4 

Upvotes: 0

Views: 13436

Answers (5)

Reto Stauffer
Reto Stauffer

Reputation: 99

Just came across this topic while looking for a nice solution for myself. Just drop this here for the future. What I'm using is the following function:

/* Assign rank to each value of the array $in. 
 * Args:
 *   in (array): Array containing as set of numeric values.
 *
 * Returns:
 *   Returns an array of the same length with ranks. Highest
 *   values of $in get rank 1, lower values get higher ranks.
 *   The same values are attributed to the same ranks.
 */
function array_rank( $in ) {
    # Keep input array "x" and replace values with rank.
    # This preserves the order. Working on a copy called $x
    # to set the ranks.
    print "input\n";
    print_r($in);
    $x = $in; arsort($x); 
    print "sorted\n";
    print_r($x);
    # Initival values
     $rank       = 0; 
    $hiddenrank = 0;
    $hold = null;
    foreach ( $x as $key=>$val ) {
        # Always increade hidden rank
        $hiddenrank += 1;
        # If current value is lower than previous:
        # set new hold, and set rank to hiddenrank.
        if ( is_null($hold) || $val < $hold ) {
            $rank = $hiddenrank; $hold = $val;
        }    
        # Set rank $rank for $in[$key]
        $in[$key] = $rank;
    }  
    print "ranking result\n";
    print_r($in);
    return $in; 
}
$a = array(140,180,180,100);
array_rank( $a ); 

The print statements (development) return the following:

input
Array
(
   [0] => 140
    [1] => 180
    [2] => 180
    [3] => 100
)
sorted
Array
(
    [2] => 180
    [1] => 180
    [0] => 140
    [3] => 100
)
ranking result
Array
(
    [0] => 3
    [1] => 1
    [2] => 1
    [3] => 4
)

In case you want to have a reverse ranking (lower values are better) simply replace arsort with asort. In my case I am ranking points, the higher the better. The array (140,180,180,100) gets the ranks (3,1,1,4). Players with the same amount of points get the same rank (in this case rank 1) while rank 2 is left out.

Upvotes: 2

krishna
krishna

Reputation: 4099

try this

$array = Array ( "0" => 12 , "1" => 17 , "2" => 5, "3" => 27, "4" => 5 );

$i=1;
foreach($array as $key=>$values)
{
    $max = max($array);
    echo "\n".$max." rank is ". $i."\n";
    $keys = array_search($max, $array);    
    unset($array[$keys]);
    if(sizeof($array) >0)
    if(!in_array($max,$array))
        $i++;

}

Demo

Upvotes: 2

Pim Verlangen
Pim Verlangen

Reputation: 387

This should work (including duplicate values having the same rank):

$values = array();
$values[0] = 5;
$values[1] = 12;
$values[2] = 19;
$values[3] = 9;
$values[4] = 5;

$ordered_values = $values;
rsort($ordered_values);

foreach ($values as $key => $value) {
    foreach ($ordered_values as $ordered_key => $ordered_value) {
        if ($value === $ordered_value) {
            $key = $ordered_key;
            break;
        }
    }
    echo $value . '- Rank: ' . ((int) $key + 1) . '<br/>';
}

Upvotes: 5

nvanesch
nvanesch

Reputation: 2600

one problem you have is that you want some return value that has 2 times an identical value and key (5=>rank4). So you cannot do an array with ranks as key nor with values as key. In this example i simply made a 2 dimensional array.

<?php

error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);

// your original input
$original = array(12, 17, 5, 27, 5);

// strip duplicates as they are ranked equally
$rankings = array_unique($original);

// apply some sorting so that the ranks are now given by the keys.
rsort($rankings);

// now just use the origincal array and lookup the rankings for each value
$return = array();
foreach($original as $value)
{
    $rankedValue = array();
    $rankedValue['value'] = $value;
    $rankedValue['rank'] = array_search($value, $rankings) + 1;
    $return[] = $rankedValue;
}

var_dump($return);

Upvotes: 0

aashnisshah
aashnisshah

Reputation: 476

You can probably sort the array by the values:

$ranked = sort($arrayValues);

after this, you can do a for loop, looping through the $ranked array, then printing the arrays in order:

for($i = 0; $i < length($ranked); $i++){
    for($j = 0; $j < length($arrayValues); $j++){
        if($arrayValues[$i] == $sorted[$j]){
            echo $arrayValues[$i] . ' has rank ' . $j;
         }
    }
}

Upvotes: -1

Related Questions