按值排序PHP数组然后键

时间:2021-07-22 11:01:22

标签: php sorting

我有以下数组:

$array = [
    'z' => 2,
    'd' => 1,
    'a' => 2,
];

现在我想按值(整数)排序​​,然后根据它是否在此许可名单中按键排序:

$allowlist = ['a', 'd'];

所以我做了以下事情:

arsort($array);
uksort($array, function($a, $b) {
    return in_array($a, $allowlist) ? -1 : 1;
});

但这会返回:

[d]: 1
[a]: 2
[z]: 2

我真正想要的是首先对值进行排序,然后如果有决胜局,则根据键是否在应导致此结果的许可名单中对键进行排序:

[a]: 2
[z]: 2
[d]: 1

2 个答案:

答案 0 :(得分:2)

您可以使用 uksort 为您提供键,并且您可以将 $array 传递到您的排序函数中以访问该值。

$array = [
    'a' => 2,
    'z' => 2,
    'd' => 1
];
$allowlist = ['a', 'd'];

uksort(
    $array,
    static function($a, $b) use ($array, $allowlist) {
        if($array[$a] === $array[$b]) {
            return in_array($a, $allowlist) ? -1 : 1;
        }
        return $array[$b] <=> $array[$a];
    }
);

这是受到这个答案的启发:https://stackoverflow.com/a/65315474/231316

此处演示:https://3v4l.org/toZIt

答案 1 :(得分:1)

我建议尽可能少进行评估和尽可能少的函数调用。

我的代码段中故意使用了两个宇宙飞船操作符——这意味着 in_array() 调用仅在必要时执行。 spaceship operator 将处理排序规则数组,但这会降低效率,因为每次迭代都会调用所有 in_array() 函数。请勿使用此 demo

代码:(Demo)

uksort(
    $array,
    fn($a, $b) =>
        $array[$b] <=> $array[$a]                                 // sort values DESC
        ?: in_array($b, $allowlist) <=> in_array($a, $allowlist)  // sort keys with priority given to whitelisted keys
);

var_export($array);

这按值降序排序,然后通过检查 in_array() 是否降序来打破平局。对布尔结果进行排序时,降序将真置于假之前。

如果您正在处理大型阵列卷,那么我会敦促您避免使用 in_array()。而是翻转您的查找数组并在您的自定义函数中使用 isset()

自定义函数的可见级联规则语法使其易于阅读和扩展。如果您想在两个或两个键都没有列入白名单时添加另一个决胜局,那么只需添加带有新规则的另一行:

?: $a <=> $b  // sort by key ascending (alphabetically)
相关问题