You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP多维数组中按answer值降序排序scores子数组并保留键名

PHP多维数组按子数组元素值降序排序(保留键名)

问题描述

我有一个PHP多维数组,需要将每个顶级元素内的scores子数组按其元素的answer值从高到低降序排序,且保留所有数组键名。尝试通过循环和自定义排序函数实现,但未成功。

原数组

$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, 
    ]
];

尝试的代码

$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');

期望排序后的数组

[
    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,
    ]
]

解决方案

你之前的代码错误地对顶级数组元素进行排序,而不是每个顶级元素内部的scores子数组。正确的做法是遍历每个顶级元素,针对其scores子数组执行排序操作,同时用uasort保留键名。

以下是可行代码:

// 遍历原数组的每个顶级元素,使用引用直接修改原数组
foreach ($array as &$item) {
    // 对scores子数组按answer值降序排序,保留键名
    uasort($item['scores'], function($a, $b) {
        // 太空船运算符实现降序:$b在前,$a在后
        return $b['answer'] <=> $a['answer'];
    });
}
// 解除引用,避免后续操作意外修改数组
unset($item);

代码说明

  1. 遍历与引用:使用foreach ($array as &$item),通过引用直接修改原数组中的每个顶级元素,无需额外复制数组。
  2. uasort函数:该函数会对数组进行排序并保留原键名,正好符合需求。
  3. 匿名排序函数:用太空船运算符<=>比较两个元素的answer值,$b['answer']在前实现降序排序;若值相等,会保持元素的原始相对顺序(稳定排序)。

内容的提问来源于stack exchange,提问作者Chris Ediger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:21:07