skip to Main Content

I have the following array that I’m attempting to sort each scores array by answer from high to low.

$array = [
    503 => [
        'scores' => [
            4573 => ['answer' => 100],
            4574 => ['answer' => 60],
            4575 => ['answer' => 100],
            4576 => ['answer' => 80],
            4577 => ['answer' => 40],
            4578 => ['answer' => 20],
            4579 => ['answer' => 60],
            4580 => ['answer' => 100],
            4581 => ['answer' => 60],
            4582 => ['answer' => 60],
            4583 => ['answer' => 80],
            4584 => ['answer' => 80],
        ],
        'category' => 'Category A',
        'grade' => 70,
        'color' => NULL
    ],
    504 => [
        'scores' => [
            4585 => ['answer' => 40],
            4586 => ['answer' => 100],
            4587 => ['answer' => 80],
            4588 => ['answer' => 60],
            4589 => ['answer' => 100],
            4590 => ['answer' => 40],
            4591 => ['answer' => 80],
            4592 => ['answer' => 60],
            4593 => ['answer' => 60],
            4594 => ['answer' => 100],
            4595 => ['answer' => 100],
            4596 => ['answer' => 80], 
        ],
        'category' => 'Category B',
        'grade' => 75,
        'color' => NULL
    ],
    505 => [
        'scores' => [
            4597 =>['answer' => 20],
            4598 =>['answer' => 80],
            4599 =>['answer' => 100],
            4600 =>['answer' => 60],
            4601 =>['answer' => 20],
            4602 =>['answer' => 20],
            4603 =>['answer' => 100],
            4604 =>['answer' => 40],
            4605 =>['answer' => 60],
            4606 =>['answer' => 100],
            4607 =>['answer' => 80],
            4608 =>['answer' => 20],
        ],
        'category' => 'Category C',
        'grade' => 58.3,
        'color' => NULL, 
    ]
];

I’ve attempted to use loops to get into the array level needed, but it isn’t working…

$temp_array_questions = $array_categorygrades;
function sortq ($a, $b) {
    $highestcountfora = 0;
    $highestcountforb = 0;
    
    foreach ($a as $thescores) {
        if (is_array($thescores)) {
            foreach ($thescores as $thequestions) {
                if (is_array($thequestions)) {
                    foreach ($thequestions as $theanswers) {
                        if ($theanswers['answer'] > $highestcountfora) {
                            $highestcountfora = $theanswers['answer'];
                        }
                    }
                }
            }
        }
    }
    
    foreach ($b as $thescores) {
        if (is_array($thescores)) {
            foreach ($thescores as $thequestions) {
                if (is_array($thequestions)) {
                    foreach ($thequestions as $theanswers) {
                        if ($theanswers['answer'] > $highestcountforb) {
                            $highestcountforb = $theanswers['answer'];
                        }
                    }
                }
            }
        }
    }
    
    if ($highestcountfora === $highestcountforb) {
        return 0;
    }
    
    return ($highestcountfora < $highestcountforb)?1:-1;
    
    //if($a['scores']['answer']==$b['scores']['answer']) return 0;
    //return $a['scores']['answer'] < $b['scores']['answer']?1:-1;
} 
uasort($temp_array_questions, 'sortq');

The array should look like this after sorting (keeping the top-level categories intact):

[
    503 => [
        'scores' => [
            4573 => ['answer' => 100],
            4575 => ['answer' => 100],
            4580 => ['answer' => 100],
            4576 => ['answer' => 80],
            4583 => ['answer' => 80],
            4584 => ['answer' => 80],
            4574 => ['answer' => 60],
            4579 => ['answer' => 60],
            4581 => ['answer' => 60],
            4582 => ['answer' => 60],
            4577 => ['answer' => 40],
            4578 => ['answer' => 20],
        ],
        'category' => 'Category A',
        'grade' => 70,
        'color' => NULL
    ],
    504 => [
        'scores' => [
            4586 => ['answer' => 100],
            4589 => ['answer' => 100],
            4594 => ['answer' => 100],
            4595 => ['answer' => 100],
            4587 => ['answer' => 80],
            4591 => ['answer' => 80],
            4596 => ['answer' => 80],
            4588 => ['answer' => 60],
            4592 => ['answer' => 60],
            4593 => ['answer' => 60],
            4585 => ['answer' => 40],
            4590 => ['answer' => 40],
        ],
        'category' => 'Category B',
        'grade' => 75,
        'color' => NULL
    ],
    505 => [
        'scores' => [
            4599 =>['answer' => 100],
            4603 =>['answer' => 100],
            4606 =>['answer' => 100],
            4598 =>['answer' => 80],
            4607 =>['answer' => 80],
            4600 =>['answer' => 60],
            4605 =>['answer' => 60],
            4604 =>['answer' => 40],
            4597 =>['answer' => 20],
            4601 =>['answer' => 20],
            4602 =>['answer' => 20],
            4608 =>['answer' => 20],
        ],
        'category' => 'Category C',
        'grade' => 58.3,
        'color' => NULL,
    ]
]

2

Answers


  1. Just use usort for each individual array of scores:

    foreach ($data as $key => $item) {
      if (!isset($item["scores"])) continue;
     
      $scores = $item["scores"];
      usort($scores, function($a, $b) {
        return $a["answer"] - $b["answer"];
      });
    
      $data[$key]["scores"] = $scores;
    
    }
    
    
    
    Login or Signup to reply.
  2. Sort the scores subsets by their answer value by calling asort() on each subset.

    I am using "array destructuring" to access only the scores subsets and & to modify the input array by reference.

    You do not need to explicitly mention answer elements because they are lone elements in their respective subarray. By default, PHP will sort by array size, then by values; because each subarray only has one element (size = 1), the sort will fallback to the answer value.

    PHP7.3 and higher: (Sort ASC Demo) (Sort DESC Demo)

    foreach ($array as ['scores' => &$scores]) {
        arsort($scores);  // or asort($scores) for ascending sorting
    }
    var_export($array);
    

    Or for PHP versions below 7.3: (Sort ASC Demo) (Sort DESC Demo)

    foreach ($array as &$row) {
        arsort($row['scores']);
    }
    var_export($array);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search