array_multisort()相等元素相对顺序未定义的含义及示例解析
关于array_multisort()中“相等元素相对顺序未定义”的解释与示例
让我来给你掰扯清楚这个点——当PHP手册说array_multisort()里相等元素的相对顺序未定义,意思就是:当你排序的数组中有多个值相等的元素时,这些元素在排序后的数组里的位置关系,是没法保证和它们在原数组里的顺序一致的。PHP不会特意去保留它们原本的相对位置,最终的顺序完全取决于底层排序算法的实现细节,你绝对不能依赖这个顺序(哪怕同版本PHP每次运行结果可能一样,也不能把它当成可靠的特性)。
为什么会这样?
这本质是因为array_multisort()使用的排序算法不是稳定排序(stable sort)。稳定排序的核心特点是:值相等的元素会严格保持它们在原数组中的相对顺序;而不稳定排序没有这个保证,相等元素的位置可能会被随机打乱(取决于算法的交换逻辑)。
实际示例
假设我们有一个存储用户ID和得分的数组:
$users = [ ['id' => 1, 'score' => 80], ['id' => 2, 'score' => 90], ['id' => 3, 'score' => 80], ['id' => 4, 'score' => 80], ['id' => 5, 'score' => 90], ];
现在我们用array_multisort()按分数升序排序:
// 提取分数列作为排序依据 $scores = array_column($users, 'score'); // 执行排序 array_multisort($scores, SORT_ASC, $users); // 输出结果 print_r($users);
你可能预期得分80的用户会保持原顺序:id1 → id3 → id4,但实际运行结果可能是id3 → id1 → id4或者其他任意顺序——因为这三个用户的分数相等,array_multisort()不会维护它们的原相对位置。
如何实现稳定排序(保留相等元素原顺序)
如果需要确保相等元素的原顺序不变,可以给每个元素添加原索引作为次要排序条件,利用原索引的唯一性来固定顺序:
// 给每个元素添加原索引标记 foreach ($users as $index => &$user) { $user['original_index'] = $index; } unset($user); // 释放引用,避免后续操作出问题 // 提取排序所需的列 $scores = array_column($users, 'score'); $originalIndices = array_column($users, 'original_index'); // 先按分数升序,再按原索引升序排序 array_multisort($scores, SORT_ASC, $originalIndices, SORT_ASC, $users); // 移除临时添加的原索引字段 foreach ($users as &$user) { unset($user['original_index']); } unset($user); // 输出稳定排序后的结果 print_r($users);
这样处理后,得分相同的用户就会严格按照他们在原数组中的顺序排列了。
内容的提问来源于stack exchange,提问作者user9098366
相关产品推荐
相关产品推荐

