Search code examples
phparrayssortingranking

Ranking with PHP on certain condition


I have marks scored by several students in php array.

$firstarray:

Array ( 
       [0] => Array ( 
             [6] => Array ( //I want to skip this student from ranking
                     [ENGLISH] => 45.00 
                     [MATHEMATICS] => 5.00 
                     [SCIENCE] => 40.00 
                    ) 
                ) 
      [1] => Array ( 
             [7] => Array ( 
                     [ENGLISH] => 41.00 
                     [MATHEMATICS] => 40.00 
                     [SCIENCE] => 47.00 
                     ) 
                ) 
      ) 
      [2] => Array ( 
             [8] => Array ( 
                     [ENGLISH] => 42.00 
                     [MATHEMATICS] => 44.00 
                     [SCIENCE] => 40.00 
                     ) 
                )
      [3] => Array ( 
             [9] => Array ( 
                     [ENGLISH] => 42.00 
                     [MATHEMATICS] => 25.00 
                     [SCIENCE] => 31.00 
                     ) 
                ) 
      )

In another array, I have the total mark scored by each student with the ranking.:

$secondarray:

Array ( [7] => 
           Array ( 
             [score] => 128 
             [rank] => 1 
            ) 
        [8] => 
           Array ( 
             [score] => 126
             [rank] => 2 
            ) 
        [9] => 
           Array ( 
             [score] => 98
             [rank] => 3 
            ) 
       [6] => 
           Array ( 
             [score] => 90 
             [rank] => 4 
            ) 
        ) 

After taking out the students total mark scored in all subjects, I used the following php code to calculate the ranking with ties:

$totalmarkscore:

   Array ( 
       [0] => Array ( 
            [6] => 90 
           ) 
       [1] => Array ( 
            [7] => 128 
           ) 
       [2] => Array ( 
            [8] => 126 
           )
       [3] => Array ( 
            [9] => 98
           ) 
       ) 

   $rankchu =array();
   foreach($totalmarkscore as $k => $vl){
      if(is_array($vl)){
          foreach($vl as $hlutna =>$ken){
             $rankchu[$hlutna]= $ken;
      }
    }
  }
  $secondarray = setRankings($rankchu);    

My question is: How do I skip calculating the rank of a student who does not get minimum 15 marks from each subject? But I still want to show the student marks scoring detail, I just want to skip it from the ranking and then maintain the ranking order. In the above example, I want to skip the student with id=6 because he did not get minimum 15 mark (he scored only 5 mark) in Mathematics from ranking calculation, other things remaining the same. Please help. Thanks.


Solution

  • When you are processing $firstarray, you will need to retain the information whether any of the scores was under 15. Here we add a can_be_scored flag to store that:

     $totalmarkscore = array_reduce(
       $firstarray,
       function($result, $item) {
         $id = key($item);
         $scores = $item[$id];
         $result[$id] = array(
           "score" => array_sum($scores),
           "can_be_scored" => min($scores) >= 15
         );
         return $result;
       },
       array()
     );
    

    With this, $totalmarkscore should look something like this:

    Array (
        [7] => 
           Array ( 
             [score] => 128 
             [can_be_scored] => true
            ) 
        [8] => 
           Array ( 
             [score] => 126
             [can_be_scored] => true
            ) 
        [9] => 
           Array ( 
             [score] => 98
             [can_be_scored] => true
            ) 
       [6] => 
           Array ( 
             [score] => 90 
             [can_be_scored] => false
            ) 
        ) 
    

    Then, in setRankings, you can check if $item["can_be_scored"] and exclude the item if it is false.