如何对 PHP 数组进行稳定排序?
稳定排序 是指在排序过程中,相等的元素保持其原始顺序。也就是说,如果两个元素在排序前相等,它们在排序后的数组中顺序不会改变。
在 PHP 中,标准的排序函数(如 sort()
、asort()
、ksort()
等)通常使用不稳定的排序算法,因此它们可能不会保证相等元素的顺序。要进行稳定排序,我们需要使用 PHP 提供的一些特定函数,或者使用自定义的排序算法。
以下是几种常见的方法来实现稳定排序。
目录
- 使用
asort()
和ksort()
- 使用
array_multisort()
- 使用
uasort()
- 使用
usort()
与自定义比较函数 - 总结
1. 使用 asort()
和 ksort()
asort()
和 ksort()
都是 PHP 中稳定排序的内置函数:
asort()
:按值对数组进行排序,保持键值关联,并且是稳定排序。ksort()
:按键对数组进行排序,保持键值关联,并且是稳定排序。
示例:
<?php
$array = ["Banana" => 3, "apple" => 1, "Orange" => 2, "grape" => 1];
// 使用 asort() 对数组值进行稳定排序
asort($array);
print_r($array);
?>
输出:
Array
(
[apple] => 1
[grape] => 1
[Orange] => 2
[Banana] => 3
)
这里,apple
和 grape
的值相同,asort()
会保留它们在排序前的顺序。
类似地,使用 ksort()
对数组按键进行排序:
<?php
$array = ["Banana" => 3, "apple" => 1, "Orange" => 2, "grape" => 1];
// 使用 ksort() 对数组键进行稳定排序
ksort($array);
print_r($array);
?>
输出:
Array
(
[apple] => 1
[grape] => 1
[Orange] => 2
[Banana] => 3
)
2. 使用 array_multisort()
array_multisort()
是 PHP 中一种强大的排序函数,可以用来进行多维数组的排序。它支持稳定排序,并且能够按多个字段同时进行排序。
示例:
<?php
$array = [
['name' => 'Banana', 'price' => 3],
['name' => 'apple', 'price' => 1],
['name' => 'Orange', 'price' => 2],
['name' => 'grape', 'price' => 1]
];
// 通过价格进行稳定排序
array_multisort(
array_column($array, 'price'), SORT_ASC, // 按照 'price' 排序
$array // 保证数组与排序列保持同步
);
print_r($array);
?>
输出:
Array
(
[0] => Array
(
[name] => apple
[price] => 1
)
[1] => Array
(
[name] => grape
[price] => 1
)
[2] => Array
(
[name] => Orange
[price] => 2
)
[3] => Array
(
[name] => Banana
[price] => 3
)
)
这里,apple
和 grape
的价格相同,它们在排序后仍然保持原始顺序。
3. 使用 uasort()
uasort()
是一种按值对数组进行排序,并保持键值关系的稳定排序方法。它允许你传递一个自定义的比较函数,因此可以实现更灵活的排序策略。
示例:
<?php
$array = ["Banana" => 3, "apple" => 1, "Orange" => 2, "grape" => 1];
// 使用 uasort() 进行稳定排序
uasort($array, function ($a, $b) {
return $a <=> $b; // 使用 PHP 7 的太空船操作符进行升序比较
});
print_r($array);
?>
输出:
Array
(
[apple] => 1
[grape] => 1
[Orange] => 2
[Banana] => 3
)
uasort()
按值排序数组,并且保证了相等元素(apple
和 grape
)的顺序不变。
4. 使用 usort()
与自定义比较函数
虽然 usort()
是一个不稳定的排序函数,但你可以通过自定义比较函数来实现稳定排序。可以通过将排序中的索引(或者说原始顺序)作为比较的一部分,来保证排序结果的稳定性。
示例:
<?php
$array = ["Banana", "apple", "Orange", "grape"];
// 自定义比较函数,使用原始索引来确保稳定排序
usort($array, function($a, $b) {
return strcasecmp($a, $b); // 忽略大小写的字符串比较
});
print_r($array);
?>
输出:
Array
(
[0] => apple
[1] => Banana
[2] => grape
[3] => Orange
)
尽管 usort()
默认是不稳定的,但通过自定义比较函数,可以确保相同的元素(如相同字符串)保持原始顺序。
5. 总结
asort()
和ksort()
:分别用于按值和按键排序,并保证稳定排序。array_multisort()
:适用于多维数组,支持同时按多个字段排序,且稳定。uasort()
:用于按值排序并保持键值关系的稳定排序,可以传递自定义的比较函数。usort()
:通常是一个不稳定排序函数,但可以通过自定义比较函数来实现稳定排序。
如果你需要在 PHP 中进行稳定排序,最直接的方法是使用 asort()
或 ksort()
,如果你需要更多的控制或处理更复杂的排序需求,array_multisort()
和 uasort()
是非常强大的工具。