php提供了丰富的内置函数处理数组排序与去重,核心在于根据数据类型和需求选择合适方法。1. 对于简单数组排序,若不需保留键,使用sort()升序或rsort()降序;2. 关联数组按值排序且保留键用asort()或arsort();3. 按键排序使用ksort()或krsort();4. 复杂排序逻辑使用usort()、uasort()或uksort()配合自定义比较函数;5. 多维数组或多个数组同步排序使用array_multisort();6. 去重首选array_unique(),但仅适用于标量值;7. 对象去重若基于实例唯一性可用splobjectstorage;8. 内容相同但实例不同的对象或复杂结构去重,可通过唯一键(如序列化或属性组合)手动去重。这些方法结合使用可高效处理各类数组操作需求。

PHP语言在处理数组的排序与去重方面,提供了相当丰富且灵活的内置函数,这使得我们能够高效地管理和操作数据。核心来看,无论是需要按值、按键,还是按自定义规则排序,亦或是移除重复元素,PHP都有成熟的解决方案。

PHP提供了多种函数来满足数组排序和去重的需求。对于排序,最常用的是
sort()
rsort()
asort()
arsort()
ksort()
krsort()
usort()
uasort()
uksort()
array_multisort()
array_unique()
数组排序:
立即学习“PHP免费学习笔记(深入)”;

sort(array &$array, int $flags = SORT_REGULAR)
$numbers = [3, 1, 4, 1, 5, 9]; sort($numbers); // $numbers 现在是 [1, 1, 3, 4, 5, 9]
rsort(array &$array, int $flags = SORT_REGULAR)
sort()
asort(array &$array, int $flags = SORT_REGULAR)
$grades = ['Math' => 90, 'Physics' => 85, 'English' => 92]; asort($grades); // $grades 现在是 ['Physics' => 85, 'Math' => 90, 'English' => 92]
arsort(array &$array, int $flags = SORT_REGULAR)
asort()
ksort(array &$array, int $flags = SORT_REGULAR)
$data = ['c' => 3, 'a' => 1, 'b' => 2]; ksort($data); // $data 现在是 ['a' => 1, 'b' => 2, 'c' => 3]
krsort(array &$array, int $flags = SORT_REGULAR)
ksort()
usort(array &$array, callable $callback)
$users = [
['name' => 'Alice', 'age' => 30],
['name' => 'Bob', 'age' => 25],
['name' => 'Charlie', 'age' => 30]
];
usort($users, function($a, $b) {
if ($a['age'] == $b['age']) {
return $a['name'] <=> $b['name']; // 如果年龄相同,按名字排序
}
return $a['age'] <=> $b['age']; // 否则按年龄排序
});
// $users 现在按年龄升序,年龄相同则按名字升序uasort()
uksort()
usort()
array_multisort()
数组去重:
array_unique(array $array, int $flags = SORT_REGULAR)
$colors = ['red', 'green', 'blue', 'red', 'yellow', 'green']; $uniqueColors = array_unique($colors); // $uniqueColors 现在是 ['red', 'green', 'blue', 'yellow']
选择正确的PHP数组排序方法,说实话,一开始确实有点让人眼花缭乱。但核心原则是:你关心的是“值”还是“键”?排序后是否需要保持原来的键?以及你的排序逻辑是不是非常个性化?

如果你的数组是简单的数字或字符串列表,且你不在乎原来的索引,
sort()
rsort()
但如果你的数组是关联数组,比如用户ID对应用户名的那种,而你希望按用户名排序,同时又不想打乱ID和用户名的对应关系,那么
asort()
arsort()
ksort()
krsort()
而当你的排序需求变得复杂,比如你有一个对象数组,每个对象都有名字、年龄、分数等属性,你想先按年龄排序,年龄相同再按分数排序,甚至分数相同再按名字排序……这种时候,内置的简单排序函数就力不从心了。这时,
usort()
uasort()
// 假设有一个商品列表,需要先按价格降序,价格相同则按库存升序
$products = [
['name' => 'Laptop', 'price' => 1200, 'stock' => 50],
['name' => 'Mouse', 'price' => 25, 'stock' => 200],
['name' => 'Keyboard', 'price' => 1200, 'stock' => 30],
['name' => 'Monitor', 'price' => 300, 'stock' => 80]
];
uasort($products, function($a, $b) {
if ($a['price'] == $b['price']) {
return $a['stock'] <=> $b['stock']; // 价格相同,按库存升序
}
return $b['price'] <=> $a['price']; // 否则按价格降序
});
/*
$products 现在是:
[
['name' => 'Keyboard', 'price' => 1200, 'stock' => 30],
['name' => 'Laptop', 'price' => 1200, 'stock' => 50],
['name' => 'Monitor', 'price' => 300, 'stock' => 80],
['name' => 'Mouse', 'price' => 25, 'stock' => 200]
]
*/这种自定义排序的能力,真的让PHP处理复杂数据变得游刃有余。
说起PHP数组去重,
array_unique()
一个常见的陷阱是类型转换。
array_unique()
==
0
"0"
null
false
"1"
1
$data = [0, "0", false, null, 1, "1"]; $uniqueData = array_unique($data); // $uniqueData 可能是 [0, 1] 或类似的,具体取决于PHP版本和内部实现,但会把0, "0", false, null 视为相同
如果你需要严格的类型比较,
array_unique
另一个大陷阱是对象和多维数组。
array_unique()
E_NOTICE
那么,高效技巧呢? 对于大多数包含标量(数字、字符串)的数组,
array_unique()
当涉及到对象去重时,就没有那么直接了。如果你想去重的是同一个对象的不同引用,PHP的
SplObjectStorage
$obj1 = new stdClass(); $obj1->id = 1;
$obj2 = new stdClass(); $obj2->id = 2;
$obj3 = new stdClass(); $obj3->id = 1; // 内容相同,但这是不同的对象实例
$objects = [$obj1, $obj2, $obj3, $obj1]; // obj1出现了两次
$storage = new SplObjectStorage();
foreach ($objects as $obj) {
$storage->attach($obj);
}
$uniqueObjects = iterator_to_array($storage);
// $uniqueObjects 包含 $obj1, $obj2, $obj3 三个不同的对象实例,即使 $obj1 引用被重复添加,SplObjectStorage 也只存储一次但如果你想去重的是“内容相同”但“实例不同”的对象,那就需要自定义逻辑了。通常的做法是给每个对象定义一个唯一的标识符(比如一个ID属性),然后把这个ID作为键存到一个临时数组里,或者在
usort
uasort
对于多维数组去重,一种常见的“黑科技”是序列化-去重-反序列化。你可以将每个子数组序列化成字符串,然后对这些字符串进行
array_unique()
$nestedArrays = [
['a' => 1, 'b' => 2],
['c' => 3, 'd' => 4],
['a' => 1, 'b' => 2], // 重复项
['e' => 5, 'f' => 6]
];
$serializedArrays = array_map('serialize', $nestedArrays);
$uniqueSerializedArrays = array_unique($serializedArrays);
$uniqueNestedArrays = array_map('unserialize', $uniqueSerializedArrays);
/*
$uniqueNestedArrays 现在是:
[
['a' => 1, 'b' => 2],
['c' => 3, 'd' => 4],
['e' => 5, 'f' => 6]
]
*/这方法虽然有效,但序列化和反序列化本身是有性能成本的,对于非常大的数组,需要权衡。
当数组里装的不再是简单的数字或字符串,而是对象或者嵌套的数组时,排序和去重就变得有意思了,因为PHP内置的那些通用函数,很多时候就不那么“智能”了。
复杂数据类型的排序:
对于包含对象的数组,最常见也最强大的工具就是
usort()
uasort()
class Product {
public $name;
public $price;
public $stock;
public function __construct($name, $price, $stock) {
$this->name = $name;
$this->price = $price;
$this->stock = $stock;
}
}
$products = [
new Product('Laptop', 1200, 50),
new Product('Mouse', 25, 200),
new Product('Keyboard', 1200, 30),
new Product('Monitor', 300, 80)
];
// 需求:先按价格降序,价格相同则按库存升序
usort($products, function(Product $a, Product $b) {
if ($a->price == $b->price) {
return $a->stock <=> $b->stock; // 价格相同,按库存升序
}
return $b->price <=> $a->price; // 否则按价格降序
});
// 此时 $products 数组中的对象已经按你定义的规则排序了对于多维数组的排序,
usort()
array_multisort()
$data = [
['name' => 'Alice', 'age' => 30, 'score' => 85],
['name' => 'Bob', 'age' => 25, 'score' => 90],
['name' => 'Charlie', 'age' => 30, 'score' => 92],
];
// 提取出需要排序的“列”
$ages = array_column($data, 'age');
$scores = array_column($data, 'score');
// 按照年龄升序,年龄相同则按分数降序
array_multisort($ages, SORT_ASC, SORT_NUMERIC,
$scores, SORT_DESC, SORT_NUMERIC,
$data);
// $data 现在按照年龄和分数排序了array_multisort()
复杂数据类型的去重:
这才是真正考验你对数据结构理解的地方。
array_unique()
对于对象去重,如果你的“去重”指的是移除完全相同的对象实例(即同一个对象在内存中的不同引用),那么前面提到的
SplObjectStorage
然而,更常见的情况是,你希望移除的是“内容相同”但可能是不同实例的对象。例如,你有两个
Product
new Product()
getUniqueKey()
md5(serialize($this))
getUniqueKey()
class Product {
public $name;
public $price;
public $stock;
public function __construct($name, $price, $stock) {
$this->name = $name;
$this->price = $price;
$this->stock = $stock;
}
// 定义一个方法来获取对象的唯一标识
public function getUniqueKey(): string {
return md5($this->name . '|' . $this->price . '|' . $this->stock);
}
}
$products = [
new Product('Laptop', 1200, 50),
new Product('Mouse', 25, 200),
new Product('Laptop', 1200, 50), // 内容重复
new Product('Monitor', 300, 80)
];
$uniqueProducts = [];
$seenKeys = [];
foreach ($products as $product) {
$key = $product->getUniqueKey();
if (!isset($seenKeys[$key])) {
$uniqueProducts[] = $product;
$seenKeys[$key] = true;
}
}
// $uniqueProducts 现在只包含内容唯一的Product对象这种方法对于多维数组去重也同样适用,只需将子数组序列化成字符串作为唯一键即可。但要记住,序列化和反序列化操作会带来额外的性能开销,对于极大的数据集,需要仔细考虑。在实际开发中,理解这些方法的原理和适用场景,能帮助你更灵活、高效地处理PHP中的复杂数组操作。
以上就是#%#$#%@%@%$#%$#%#%#$%@_e1bfd762321e409cee4ac0b6e841963c语言怎样实现数组的排序与去重功能 php语言数组排序去重的详细方法教程的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号