0

I am trying to calculate rank based on grouping of score.

Here is the example of data, the actual data is dynamic. higher and lowest score depends on result value.

$data = array(
    array('id' => 1, 'name' => 'John Snow', 'score' => 80),
    array('id' => 2, 'name' => 'John Fire', 'score' => 50),
    array('id' => 3, 'name' => 'John Water', 'score' => 79),
    array('id' => 4, 'name' => 'John Leaf', 'score' => 80),
);

The result printout would be by id:

ID   Name       Score Rank
1    John Snow  80    1
2    John Fire  50    3
3    John Water 79    2
4    John Leaf  80    1

Thanks!

rslhdyt
  • 149
  • 2
  • 14

2 Answers2

3

I used rsort()

$data = array(
    array('id' => 1, 'name' => 'John Snow', 'score' => 80),
    array('id' => 2, 'name' => 'John Fire', 'score' => 50),
    array('id' => 3, 'name' => 'John Water', 'score' => 79),
    array('id' => 4, 'name' => 'John Leaf', 'score' => 80),
);


$score = array();
foreach ($data as $idx => $dataInd) {
    $score[$dataInd['score']] = $dataInd['score'];
}

rsort($score);

foreach ($data as $idx => $dataInd) {
    $data[$idx]['rank'] = array_search($dataInd['score'], $score) + 1; 
}

var_dump($data);

this will result to:

array (size=4)
  0 => 
    array (size=4)
      'id' => int 1
      'name' => string 'John Snow' (length=9)
      'score' => int 80
      'rank' => int 1
  1 => 
    array (size=4)
      'id' => int 2
      'name' => string 'John Fire' (length=9)
      'score' => int 50
      'rank' => int 3
  2 => 
    array (size=4)
      'id' => int 3
      'name' => string 'John Water' (length=10)
      'score' => int 79
      'rank' => int 2
  3 => 
    array (size=4)
      'id' => int 4
      'name' => string 'John Leaf' (length=9)
      'score' => int 80
      'rank' => int 1
Eddie
  • 26,593
  • 6
  • 36
  • 58
2

Here is code to assign non-unique ranks to each person in array:

$data = array(...);

// create hash map with unique scores
$scores = array();
foreach ($data as $v)
    $scores[$v['score']] = 1;

// sort by keys
krsort($scores);

// assign proper ranks to each score 
$rank = 1;
foreach ($scores as &$v)
    $v = $rank++;

// assign ranks
foreach ($data as &$v)
    $v['rank'] = $scores[$v['score']];

print_r($data);

To understand how it works I suggest you to add print_r($scores); after each operation to see what is going on with it

Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57