I'm building a student result system now i want to sort the students according to their average scores, I have an array like this
Array (
[0] => Array (
[student] => STD-000001
[marks] => 78
[total_subjects] => 1
[avarage] => 78
)
[1] => Array (
[student] => STD-000002
[marks] => 60.4
[total_subjects] => 1
[avarage] => 60.4
)
[2] => Array (
[student] => STD-000013
[marks] => 0
[total_subjects] => 0
[avarage] => 0
)
[3] => Array (
[student] => STD-000014
[marks] => 0
[total_subjects] => 0
[avarage] => 0
)
)
now I want to sort the array by avarage
key then create a new array by adding a new key position
. I expect an array like this
Array (
[0] => Array (
[student] => STD-000001
[marks] => 78
[total_subjects] => 1
[avarage] => 78
[position] => 1 )
[1] => Array (
[student] => STD-000002
[marks] => 60.4
[total_subjects] => 1
[avarage] => 60.4
[position] => 2
)
[2] => Array (
[student] => STD-000013
[marks] => 0
[total_subjects] => 0
[avarage] => 0
[position] => 3
)
[3] => Array (
[student] => STD-000014
[marks] => 0
[total_subjects] => 0
[avarage] => 0
[position] => 3
)
)
As you can see the greater average
the earlier the position
, and if the average
matches it should have the same position
value. i have tried methods like
$class_students is the array above
$sort_col = [];
foreach ($class_students as $key => $row) {
$sort_col[$key] = $row['avarage'];
}
array_multisort($sort_col, SORT_DESC, SORT_NUMERIC, $class_students);
This works by sorting the 'average' but i cant find a way to add a new key 'position' in array.
usort is the function you should use.
function compare($a, $b)
{
return $b->average - $a->average;
}
usort($students, "compare");
As for the position - you don't need a position property.
Just use the index after sorting the array.
foreach ($students as $key => $value) {
$position = $key+1;
//if you really insist on having that property:
$students[$key]['position'] = $key+1;
}
You can sort using array_column($class_students, 'avarage')
which will remove your foreach loop. The you can traverse array and add new key-value in it by comparing avg.
array_multisort(array_column($class_students, 'avarage'), SORT_DESC, SORT_NUMERIC, $class_students);
$last_avg = "";
$pos = 0;
foreach ($class_students as $key => &$value) {
$avg = $value['avarage'];
if($last_avg != $avg)
$pos++;
$value['position']=$pos;
$last_avg = $avg;
}
First use usort
, like so:
usort($class_students, function ($a, $b) {
return $a['avarage'] < $b['avarage'];
});
Lastly, use following to add position:
$pos = 1;
foreach ($class_students as $key => $value) {
if ($key > 0 && $value['avarage'] < $class_students[$key - 1]['avarage']) {
$pos += 1;
}
$class_students[$key]['position'] = $pos;
}
I shuffled the original array, and tested above code, here is the output:
Array
(
[0] => Array
(
[student] => STD-000001
[marks] => 78
[total_subjects] => 1
[avarage] => 78
[position] => 1
)
[1] => Array
(
[student] => STD-000002
[marks] => 60.4
[total_subjects] => 1
[avarage] => 60.4
[position] => 2
)
[2] => Array
(
[student] => STD-000014
[marks] => 0
[total_subjects] => 0
[avarage] => 0
[position] => 3
)
[3] => Array
(
[student] => STD-000013
[marks] => 0
[total_subjects] => 0
[avarage] => 0
[position] => 3
)
)
You can use array_column to get all the values and sort them.
Then use the new array keys in a loop to build your result array and add position.
$avarage = array_column($arr, "avarage");
Arsort($avarage); //sort on values.
$i=0;
Foreach($avarage as $key => $val){
$res[$i] = $arr[$key];
$res[$i]['position'] = $i+1;
$i++;
}
Var_dump($res);