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

PHP如何修改sortBySubValue函数实现多层子数组排序

PHP按二维关联数组的子数组字段多层排序问题

问题描述

我之前参考过相关实现,打算复用Pigalev Pavel提供的sortBySubValue函数实现排序,但我的场景里待排序的字段是一层子数组,调用函数后排序没有生效。

我的数组结构如下:

$players = array(
    array(
        "name" => "Woods",
        "countback" => array(
            "9" => 17,
            "6" => 11,
            "3" => 6,
            "1" => 2
        )
    ),
    array(
        "name" => "Spieth",
        "countback" => array(
            "9" => 17,
            "6" => 12,
            "3" => 4,
            "1" => 2
        )
    ),
    array(
        "name" => "McIlroy",
        "countback" => array(
            "9" => 17,
            "6" => 12,
            "3" => 5,
            "1" => 1
        )
    ),
    array(
        "name" => "Johnson",
        "countback" => array(
            "9" => 17,
            "6" => 12,
            "3" => 5,
            "1" => 2
        )
    )
);

我需要按照countback子数组的键序(按9、6、3、1的顺序依次比对)降序排列父数组,预期排序结果:

  1. Johnson 排第一,最后一级比对值2最高
  2. McIlroy 排第二,最后一级比对值1更低
  3. Spieth 排第三,第三级比对值4低于剩余选手
  4. Woods 排第四,第二级比对值11低于其他选手

原函数代码如下:

/**
 * @param array $array
 * @param string $value
 * @param bool $asc - ASC (true) or DESC (false) sorting
 * @param bool $preserveKeys
 * @return array
 * */
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false)
{
    if (is_object(reset($array))) {
        $preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) {
            return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} <=> $b->{$value}) * ($asc ? 1 : -1);
        }) : usort($array, function ($a, $b) use ($value, $asc) {
            return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} <=> $b->{$value}) * ($asc ? 1 : -1);
        });
    } else {
        $preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) {
            return $a[$value] == $b[$value] ? 0 : ($a[$value] <=> $b[$value]) * ($asc ? 1 : -1);
        }) : usort($array, function ($a, $b) use ($value, $asc) {
            return $a[$value] == $b[$value] ? 0 : ($a[$value] <=> $b[$value]) * ($asc ? 1 : -1);
        });
    }
    return $array;
}

我直接调用后打印原$players数组,顺序没有变化。


解决方案

排序不生效的问题修复

原函数不会修改传入的原数组,而是返回排序后的新数组,你需要接收函数返回值,而不是直接打印原数组:

$sortedPlayers = sortBySubValue($players, 'countback', false);
print_r($sortedPlayers);

多层子数组比对适配

PHP内置的数组比较运算符<=>本身就支持按元素顺序逐层比对,正好匹配你的countback排序规则,不需要修改原函数的核心逻辑,只要确认countback数组的键顺序是你要比对的优先级顺序即可(你的示例里键序正好是9、6、3、1,符合要求)。

如果后续需要自定义比对的键顺序,可以调整回调逻辑手动指定比对优先级:

// 手动指定比对的键优先级示例
$sortKeys = ['9','6','3','1'];
foreach ($sortKeys as $key) {
    if ($a['countback'][$key] != $b['countback'][$key]) {
        return ($a['countback'][$key] <=> $b['countback'][$key]) * ($asc ? 1 : -1);
    }
}
return 0;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 21:54:00