本文目录导读:

- 核心函数:
array_intersect() - 基本用法(纯值数组的交集)
- 处理关联数组(键值对交集)
- 根据键名交集的特殊情况:
array_intersect_key() - 多维数组的纯交集(手动实现)
- 总结:你要的“纯交集”解决方案
在 PHP 中,获取纯交集(即多个数组共有的元素,且结果中不包含重复值)最标准的方法是使用 array_intersect() 函数。
下面我将详细说明如何使用它,并给出针对不同数据结构的示例。
核心函数:array_intersect()
- 功能:计算多个数组的交集。
- 返回值:返回一个数组,该数组包含了在所有参数数组中都存在的键值(根据值比较)。
- 注意:它比较的是数组的值,且保留第一个数组中的键名。
基本用法(纯值数组的交集)
假设你有几个数组,想找出它们共同拥有的元素。
<?php $array1 = [1, 2, 3, 4, 5, 5, 6]; // 注意这里有重复值 $array2 = [3, 4, 5, 6, 7, 8]; $array3 = [5, 6, 9, 10]; // 计算三个数组的交集 $intersection = array_intersect($array1, $array2, $array3); // 结果会保留 $array1 中的键,但值不重复 print_r($intersection); ?>
输出结果:
Array
(
[4] => 5
[5] => 6
)
解释:
- 只有
5和6同时出现在所有三个数组中。 - 结果中只有两个元素,
array_intersect()已经帮你去重了(尽管$array1里有两个5)。 - 键名
4和5来自于$array1中第一次出现5和6的位置。
如果你想重新索引(从0开始排序):
$result = array_values($intersection); // 变成 [5, 6]
处理关联数组(键值对交集)
如果你处理的是关联数组,并且想根据值进行交集:
<?php $array1 = ['a' => 'apple', 'b' => 'banana', 'c' => 'cherry']; $array2 = ['d' => 'banana', 'e' => 'cherry', 'f' => 'date']; $array3 = ['g' => 'cherry', 'h' => 'elderberry']; $intersection = array_intersect($array1, $array2, $array3); print_r($intersection); ?>
输出结果:
Array
(
[c] => cherry
)
解释: 只有 cherry 出现在所有三个数组中。
根据键名交集的特殊情况:array_intersect_key()
如果你需要根据数组的键名来取交集(比如两个配置数组,只取共同配置项):
<?php $defaults = ['theme' => 'dark', 'lang' => 'en', 'debug' => false]; $user_settings = ['lang' => 'zh', 'theme' => 'light']; // 用户只设置了这两个 // 只保留在 $defaults 和 $user_settings 中都存在的键 $valid_settings = array_intersect_key($defaults, $user_settings); print_r($valid_settings); ?>
输出结果:
Array
(
[theme] => dark // 值来自第一个数组 $defaults
[lang] => en // 值来自第一个数组 $defaults
)
常用场景: 只允许用户修改已存在的配置项,防止注入新键。
多维数组的纯交集(手动实现)
array_intersect() 只能处理一维数组,对于多维数组(比如包含对象的数组),你需要自定义比较方式。
示例:处理对象数组的交集
假设你有一个用户对象数组,想找出同时出现在两个数组中的用户(根据 id 判断)。
<?php
class User {
public $id;
public $name;
public function __construct($id, $name) {
$this->id = $id;
$this->name = $name;
}
}
$group1 = [new User(1, 'Alice'), new User(2, 'Bob'), new User(3, 'Charlie')];
$group2 = [new User(2, 'Bob'), new User(3, 'Charlie'), new User(4, 'David')];
// 方法1:提取ID数组,使用 array_intersect
$ids1 = array_map(fn($u) => $u->id, $group1);
$ids2 = array_map(fn($u) => $u->id, $group2);
$common_ids = array_intersect($ids1, $ids2);
// 然后从第一个数组中过滤出共同ID的用户
$common_users = array_filter($group1, fn($user) => in_array($user->id, $common_ids));
// 重新索引
$common_users = array_values($common_users);
print_r($common_users); // 输出 Bob(id=2) 和 Charlie(id=3)
?>
方法2(更简洁,使用 usort 或 array_uintersect):
// 使用 array_uintersect 进行自定义比较
$common_users = array_uintersect($group1, $group2, function($a, $b) {
return $a->id <=> $b->id; // 太空船运算符,比较 id
});
// 注意: array_uintersect 会保留第一个数组的键,可能不连续
$common_users = array_values($common_users);
你要的“纯交集”解决方案
| 场景 | 推荐函数 | 说明 |
|---|---|---|
| 两个或多个一维数组 | array_intersect() |
最直接,默认去重。 |
| 根据键名交集 | array_intersect_key() |
只比较键名,不比较值。 |
| 数组值有重复,想彻底去重 | array_intersect() |
自带去重效果。 |
| 多维数组/对象数组交 | array_uintersect() |
需要自定义比较回调函数。 |
对于你问题中的“纯交集”,最推荐的就是 array_intersect(),它直接、高效,并且会自动过滤掉重复项,确保结果是每个元素只出现一次的集合。