array_unique()函数可直接去重并保留首次出现的键值,结合array_values()可重新索引,处理复杂类型时需手动遍历或序列化,灵活应对对象和嵌套数组去重需求。

在PHP中,对数组进行去重,最直接、最常用的方式就是利用内置的
array_unique()
array_unique()
$originalArray = [1, 2, 3, 2, 4, 1, 5];
$uniqueArray = array_unique($originalArray);
print_r($uniqueArray);
/*
输出:
Array
(
[0] => 1
[1] => 2
[2] => 3
[4] => 4
[6] => 5
)
*/从上面的例子可以看出,
array_unique()
array_values()
$originalArray = [1, 2, 3, 2, 4, 1, 5];
$uniqueArray = array_values(array_unique($originalArray));
print_r($uniqueArray);
/*
输出:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
*/array_unique()
sort_flags
立即学习“PHP免费学习笔记(深入)”;
SORT_REGULAR
SORT_NUMERIC
SORT_STRING
SORT_LOCALE_STRING
SORT_NATURAL
natsort()
比如,如果你有一些字符串数字,但想按数值去重:
$numbersAsString = ["10", "2", "10", "3", "2"];
$uniqueNumeric = array_unique($numbersAsString, SORT_NUMERIC);
print_r($uniqueNumeric);
/*
输出:
Array
(
[0] => 10
[1] => 2
[3] => 3
)
*/这里
SORT_NUMERIC
array_unique()
说实话,
array_unique()
处理对象: 默认情况下,
array_unique()
__toString()
__toString()
Object of class Foo could not be converted to string
stdClass
如果你想基于对象的特定属性去重,或者更复杂的逻辑,
array_unique()
class User {
public $id;
public $name;
public function __construct($id, $name) {
$this->id = $id;
$this->name = $name;
}
}
$users = [
new User(1, 'Alice'),
new User(2, 'Bob'),
new User(1, 'Alicia'), // ID重复
new User(3, 'Charlie'),
new User(2, 'Robert') // ID重复
];
$uniqueUsers = [];
$seenIds = [];
foreach ($users as $user) {
if (!isset($seenIds[$user->id])) {
$uniqueUsers[] = $user;
$seenIds[$user->id] = true;
}
}
print_r($uniqueUsers);
/*
输出会是:
Array
(
[0] => User Object
(
[id] => 1
[name] => Alice
)
[1] => User Object
(
[id] => 2
[name] => Bob
)
[2] => User Object
(
[id] => 3
[name] => Charlie
)
)
*/这种手动遍历的方式虽然稍微麻烦点,但能精确控制去重逻辑。
处理嵌套数组:
array_unique()
Array to string conversion
Array
要对嵌套数组去重,一种比较巧妙的方法是,将每个子数组序列化成字符串,然后对这些字符串进行
array_unique()
$nestedArrays = [
['a' => 1, 'b' => 2],
['x' => 1, 'y' => 2],
['a' => 1, 'b' => 2], // 重复
['c' => 3, 'd' => 4],
['b' => 2, 'a' => 1] // 值相同但键序不同
];
// 先序列化每个子数组
$serializedArrays = array_map('serialize', $nestedArrays);
print_r($serializedArrays);
// 对序列化后的字符串去重
$uniqueSerializedArrays = array_unique($serializedArrays);
print_r($uniqueSerializedArrays);
// 再反序列化回数组
$uniqueNestedArrays = array_map('unserialize', $uniqueSerializedArrays);
print_r($uniqueNestedArrays);
/*
输出会是:
Array
(
[0] => Array
(
[a] => 1
[b] => 2
)
[1] => Array
(
[x] => 1
[y] => 2
)
[3] => Array
(
[c] => 3
[d] => 4
)
)
*/需要注意的是,
serialize()
['a' => 1, 'b' => 2]
['b' => 2, 'a' => 1]
ksort()
array_unique()
除了
array_unique()
1. array_flip()
array_keys()
array_flip()
array_flip()
array_keys()
$data = ['apple', 'banana', 'orange', 'apple', 'grape'];
$uniqueData = array_keys(array_flip($data));
print_r($uniqueData);
/*
输出:
Array
(
[0] => apple
[1] => banana
[2] => orange
[3] => grape
)
*/array_unique()
true
false
1
0
null
array_flip()
array_keys()
array_unique()
2. 手动遍历与哈希表(或临时数组)检查: 这是最基础,也是最灵活的方法。通过循环遍历原数组,将每个值放入一个临时数组(通常作为键),或者用
in_array()
// 方法A:使用临时数组作为哈希表
$data = ['apple', 'banana', 'orange', 'apple', 'grape'];
$seen = [];
$uniqueData = [];
foreach ($data as $value) {
if (!isset($seen[$value])) { // 检查值是否已经存在
$uniqueData[] = $value;
$seen[$value] = true;
}
}
print_r($uniqueData);
// 方法B:使用 in_array() (性能较低)
$data = ['apple', 'banana', 'orange', 'apple', 'grape'];
$uniqueData = [];
foreach ($data as $value) {
if (!in_array($value, $uniqueData)) {
$uniqueData[] = $value;
}
}
print_r($uniqueData);in_array()
in_array()
isset($seen[$value])
3. 使用 array_reduce()
array_filter()
$data = [
['id' => 1, 'name' => 'A'],
['id' => 2, 'name' => 'B'],
['id' => 1, 'name' => 'C'], // id重复
['id' => 3, 'name' => 'D']
];
$uniqueData = array_reduce($data, function ($carry, $item) {
// 使用 id 作为键,确保唯一性
$carry[$item['id']] = $item;
return $carry;
}, []);
// 如果需要重新索引,可以再 array_values
$uniqueData = array_values($uniqueData);
print_r($uniqueData);
/*
输出:
Array
(
[0] => Array
(
[id] => 1
[name] => C
)
[1] => Array
(
[id] => 2
[name] => B
)
[2] => Array
(
[id] => 3
[name] => D
)
)
*/这个例子中,
array_reduce()
['id' => 1, 'name' => 'C']
['id' => 1, 'name' => 'A']
array_reduce()
array_unique()
in_array()
在我看来,选择哪种方法,真的得看你的具体需求:是简单去重、性能优先、还是需要高度自定义的比较逻辑。大多数情况下,
array_unique()
array_unique()
array_unique()
['a' => 'apple', 'b' => 'banana', 'c' => 'apple']
array_unique()
['a' => 'apple', 'b' => 'banana']
'a'
'b'
'c'
'apple'
'a'
'apple'
'c'
默认行为的演示:
$dataWithKeys = [
'first' => 'red',
'second' => 'blue',
'third' => 'red', // 值 'red' 重复
'fourth' => 'green',
'fifth' => 'blue' // 值 'blue' 重复
];
$uniqueData = array_unique($dataWithKeys);
print_r($uniqueData);
/*
输出:
Array
(
[first] => red
[second] => blue
[fourth] => green
)
*/可以看到,
'first'
'second'
何时这种默认行为是理想的? 当你的数组键名本身就带有某种意义,并且你希望在去重后,依然能够通过这些有意义的键来访问数据时,
array_unique()
如何灵活控制键名的保留?
虽然
array_unique()
1. 重新索引数组: 这是最常见的需求之一。如果你根本不关心原始键名,只想得到一个从
0
array_values()
$dataWithKeys = ['a' => 'apple', 'b' => 'banana', 'c' => 'apple'];
$reindexedUniqueData = array_values(array_unique($dataWithKeys));
print_r($reindexedUniqueData);
/*
输出:
Array
(
[0] => apple
[1] => banana
)
*/这基本上就是丢弃所有原始键名,然后重新生成新的数字键名。
2. 保留重复值的“最后一个”键:
array_unique()
array_unique()
array_reverse()
array_unique()
array_reverse()
$dataWithKeys = [
'first' => 'red',
'second' => 'blue',
'third' => 'red', // 最后一个 'red'
'fourth' => 'green',
'fifth' => 'blue' // 最后一个 'blue'
];
// 1. 反转数组,这样原先的“最后一个”就成了“第一个”
$reversedData = array_reverse($dataWithKeys, true); // true 保留键名
print_r($reversedData);
// 2. 对反转后的数组去重,会保留现在是“第一个”的元素(即原以上就是如何在PHP中对数组去重?array_unique()函数的实际应用的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号