给你两个或多个数组,你想知道第一个数组里有哪些值在其他数组里也出现过?array_intersect()就是干这个的。
它比较数组的值,返回第一个数组中存在于所有其他数组的元素。键名会保留(用第一个数组的键名)。这个函数从PHP 4.0.1就有了。
语法格式
array array_intersect(array $array1, array $array2 [, array $... ]): array
参数说明:
| 参数 | 说明 | 必填? |
|---|---|---|
| array1 | 基准数组 | 必填 |
| array2 | 第一个对比数组 | 必填 |
| array3... | 更多对比数组 | 可选 |
返回值: 返回一个数组,包含所有在array1中存在并且在其他所有数组中都存在的值。
和array_intersect_assoc()的区别
| 函数 | 比较内容 | 保留条件 |
|---|---|---|
| array_intersect() | 只比较值 | 值在其他数组中出现就行 |
| array_intersect_assoc() | 键名+值 | 键名和值都必须在其他数组中 |
示例1:基础用法
<?php
$students_a = ["张伟", "李芳", "王磊", "赵敏"];
$students_b = ["王磊", "刘强", "张伟", "陈晨"];
$common = array_intersect($students_a, $students_b);
print_r($common);
?>
输出:
Array
(
[0] => 张伟
[2] => 王磊
)
"张伟"和"王磊"在两个数组中都出现了。注意键名保留了原数组的位置(0和2),没有重新索引。
示例2:多个数组比较
<?php
$group_a = ["PHP", "Java", "Python", "C++", "JavaScript"];
$group_b = ["Python", "Java", "Go", "PHP"];
$group_c = ["Java", "Python", "Ruby", "PHP"];
$common_all = array_intersect($group_a, $group_b, $group_c);
print_r($common_all);
?>
输出:
Array
(
[0] => PHP
[1] => Java
[2] => Python
)
值必须在三个数组中都存在才会被保留。"C++"和"JavaScript"不在group_b或group_c中;"Go"不在group_a中;"Ruby"不在group_a中。只有PHP、Java、Python三个交集。
示例3:关联数组(只比较值)
<?php
$product_prices_a = [
"keyboard" => 299,
"mouse" => 89,
"monitor" => 1250,
"headset" => 350
];
$product_prices_b = [
"kb" => 299,
"ms" => 89,
"hp" => 450,
"hd" => 350
];
$common_prices = array_intersect($product_prices_a, $product_prices_b);
print_r($common_prices);
?>
输出:
Array
(
[keyboard] => 299
[mouse] => 89
[headset] => 350
)
注意:虽然键名不同(keyboard vs kb,mouse vs ms),但值299、89、350在两个数组中都存在,所以被保留。返回值用的还是第一个数组的键名。
个人经验分享
-
什么时候用array_intersect?
-
找出两个列表的共同元素(忽略位置和键名)
-
数据去重后找重叠部分
-
权限交集:用户拥有的权限和某个角色权限的重叠
-
标签系统:找同时拥有多个标签的内容
-
-
重复值的情况
$arr1 = ["apple", "apple", "banana"]; $arr2 = ["apple", "orange"]; $result = array_intersect($arr1, $arr2); // 结果:["apple", "apple"] 两个apple都保留第一个数组中重复的值,只要匹配上就会全部保留。
-
性能方面
array_intersect()内部会先对数组做某种形式的索引,比嵌套循环快得多。但如果数组非常大(几十万级),仍然可能较慢。 -
和array_uintersect()的区别
-
array_intersect():用内置的比较规则(值相等就算匹配) -
array_uintersect():用用户自定义回调函数比较值
-
示例4:代码号学习编程场景
<?php
// 场景:找出三个班级都选修的公共课程
$class_a_courses = ["PHP", "MySQL", "JavaScript", "Laravel", "Git"];
$class_b_courses = ["Python", "PHP", "Git", "Django", "JavaScript"];
$class_c_courses = ["Java", "PHP", "Git", "JavaScript", "Spring"];
$common_courses = array_intersect($class_a_courses, $class_b_courses, $class_c_courses);
$unique_to_a = array_diff($class_a_courses, $class_b_courses, $class_c_courses);
echo "三个班都有的课程:\n";
print_r($common_courses);
echo "\n只有A班才有的课程:\n";
print_r($unique_to_a);
?>
输出:
三个班都有的课程:
Array
(
[0] => PHP
[3] => Git
[2] => JavaScript
)
只有A班才有的课程:
Array
(
[1] => MySQL
[3] => Laravel
)
示例5:过滤保留特定值
<?php
$all_products = [
"机械键盘",
"游戏鼠标",
"显示器",
"降噪耳机",
"摄像头",
"鼠标垫"
];
$allowed_categories = ["键盘", "鼠标", "耳机", "显示器"];
// 只保留类别匹配的产品
function filter_by_keywords($items, $keywords) {
$filtered = [];
foreach ($items as $item) {
foreach ($keywords as $kw) {
if (strpos($item, $kw) !== false) {
$filtered[] = $item;
break;
}
}
}
return $filtered;
}
$allowed_products = filter_by_keywords($all_products, $allowed_categories);
print_r($allowed_products);
?>
输出:
Array
(
[0] => 机械键盘
[1] => 游戏鼠标
[2] => 显示器
[3] => 降噪耳机
)
这个例子不是直接用array_intersect,因为需要模糊匹配。但展示了交集思路在开发中的应用。
示例6:多维数组的交集
<?php
// array_intersect()不递归处理多维数组
$users_a = [
["id" => 1, "name" => "张伟"],
["id" => 2, "name" => "李芳"],
["id" => 3, "name" => "王磊"]
];
$users_b = [
["id" => 2, "name" => "李芳"],
["id" => 3, "name" => "王磊"],
["id" => 4, "name" => "赵敏"]
];
// 直接比较多维数组会比较整个子数组
$common_users = array_intersect($users_a, $users_b);
print_r($common_users);
?>
输出:
Array
(
[1] => Array
(
[id] => 2
[name] => 李芳
)
[2] => Array
(
[id] => 3
[name] => 王磊
)
)
只要子数组的值相同(顺序、键名、值都一致),就会被视为匹配。如果要按某个字段(如id)比较,需要自己写逻辑或用array_uintersect()。
示例7:配合array_values重新索引
<?php
$arr1 = [5 => "apple", 8 => "banana", 12 => "orange"];
$arr2 = ["banana", "apple", "grape"];
$intersect = array_intersect($arr1, $arr2);
print_r($intersect);
// 如果需要连续索引
$reindexed = array_values($intersect);
print_r($reindexed);
?>
输出:
Array
(
[5] => apple
[8] => banana
)
Array
(
[0] => apple
[1] => banana
)
本节课程知识要点
-
array_intersect()返回第一个数组中存在于其他所有数组的值 -
只比较值,不比较键名
-
至少需要两个数组,可以传入更多
-
保留第一个数组的键名(不重新索引)
-
和
array_intersect_assoc()的区别:后者同时比较键名 -
第一个数组中的重复值会全部保留(只要匹配上)
-
从PHP 4.0.1开始可用