array_intersect

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

array_intersect计算数组的交集

描述

array_intersect(array $array, array ...$arrays): array

array_intersect() 返回一个数组,该数组包含所有存在于所有参数中的 array 的值。注意,键被保留。

参数

array

要检查的主值数组。

arrays

要比较值的数组。

返回值

返回一个数组,该数组包含 array 中所有其值存在于所有参数中的值。

变更日志

版本 描述
8.0.0 此函数现在可以仅使用一个参数调用。以前,至少需要两个参数。

示例

示例 #1 array_intersect() 示例

<?php
$array1
= array("a" => "green", "red", "blue");
$array2 = array("b" => "green", "yellow", "red");
$result = array_intersect($array1, $array2);
print_r($result);
?>

上面的示例将输出

Array
(
    [a] => green
    [0] => red
)

注释

注意: 两个元素被认为相等,当且仅当 (string) $elem1 === (string) $elem2。换句话说:当字符串表示形式相同的时候。

参见

添加注释

用户贡献注释 34 notes

stuart at horuskol dot co dot uk
16 年前
此函数键保留的更清晰示例

<?php

$array1
= array(2, 4, 6, 8, 10, 12);
$array2 = array(1, 2, 3, 4, 5, 6);

var_dump(array_intersect($array1, $array2));
var_dump(array_intersect($array2, $array1));

?>

产生以下结果

array(3) {
[0]=> int(2)
[1]=> int(4)
[2]=> int(6)
}

array(3) {
[1]=> int(2)
[3]=> int(4)
[5]=> int(6)
}

这使得记住将数组传递给函数的顺序变得很重要,如果脚本后面依赖这些键的话。
theking at king dot ma
2 年前
我使用 array_intersect 快速检查 $_GET 参数;

<?php declare(strict_types=1)

$_params = ['cust_id','prod_id'];
$_params_check = array_intersect(array_keys($_GET),$_params);
if(
count($_params_check) !== count($_params)) {
header("HTTP/1.1 400 Bad Request");
die();
}
?>

如果 $_GET 中缺少 cust_id 或 prod_id 或两者都缺少,则该文件将以 400 错误结束。但显然也可以在 $_POST 和 $_REQUEST 上使用它。
匿名
3 年前
array_intersect 使用值,而不是回调
array_uintersect 使用值,回调接收值
array_intersect_key 使用键,而不是回调
array_intersect_ukey 使用键,回调接收键
array_intersect_assoc 使用两者,而不是回调
array_intersect_uassoc 使用两者,回调仅接收键
array_uintersect_assoc 使用两者,回调仅接收值
array_uintersect_uassoc 使用两者,一个回调接收键,另一个接收值。
Niels
17 年前
这里有一个 array_union($a, $b)

<?php
// $a = 1 2 3 4
$union = // $b = 2 4 5 6
array_merge(
array_intersect($a, $b), // 2 4
array_diff($a, $b), // 1 3
array_diff($b, $a) // 5 6
); // $u = 1 2 3 4 5 6
?>
Shawn Pyle
15 年前
array_intersect 对数组中的重复项进行不同的处理。如果第一个数组中有重复项,则将返回所有匹配的重复项。如果任何后续数组中有重复项,则不会返回它们。

<?php
array_intersect
(array(1,2,2),array(1,2,3)); //=> array(1,2,2)
array_intersect(array(1,2,3),array(1,2,2)); //=> array(1,2)
?>
sapenov at gmail dot com
19 年前
如果您需要提供任意数量的参数
给 array_intersect() 或其他数组函数,
使用以下函数

$full=call_user_func_array('array_intersect', $any_number_of_arrays_here);
blu at dotgeek dot org
19 年前
请注意,`array_intersect` 和 `array_unique` 不适用于多维数组。
例如,如果您有以下数组:

<?php

$orders_today
[0] = array('John Doe', 'PHP Book');
$orders_today[1] = array('Jack Smith', 'Coke');

$orders_yesterday[0] = array('Miranda Jones', 'Digital Watch');
$orders_yesterday[1] = array('John Doe', 'PHP Book');
$orders_yesterday[2] = array('Z? da Silva', 'BMW Car');

?>

并且您想了解今天和昨天是否有人购买了相同的东西,并使用 `array_intersect($orders_today, $orders_yesterday)`,您将得到以下结果:

<?php

Array
(
[
0] => Array
(
[
0] => John Doe
[1] => PHP Book
)

[
1] => Array
(
[
0] => Jack Smith
[1] => Coke
)

)

?>

但是,我们可以通过序列化内部数组来解决这个问题。
<?php

$orders_today
[0] = serialize(array('John Doe', 'PHP Book'));
$orders_today[1] = serialize(array('Jack Smith', 'Coke'));

$orders_yesterday[0] = serialize(array('Miranda Jones', 'Digital Watch'));
$orders_yesterday[1] = serialize(array('John Doe', 'PHP Book'));
$orders_yesterday[2] = serialize(array('Z? da Silva', 'Uncle Tungsten'));

?>

这样,`array_map("unserialize", array_intersect($orders_today, $orders_yesterday))` 将返回:

<?php

Array
(
[
0] => Array
(
[
0] => John Doe
[1] => PHP Book
)

)

?>

显示了谁在今天和昨天购买了相同的东西 =)

[]s
yuval at visualdomains dot com
9 年前
使用 `isset` 来实现这一点,通常更快

<?php

$m
= range(1,1000000);
$s = [2,4,6,8,10];

// 使用 array_intersect 返回所有同时存在于 $m 和 $s 中的值
$tstart = microtime(true);
print_r (array_intersect($m,$s));
$tend = microtime(true);
$time = $tend - $tstart;
echo
"Took $time";

// 使用 array_flip 和 isset 返回所有同时存在于 $m 和 $s 中的值
$tstart = microtime(true);
$f = array_flip($s);
/* $f 现在看起来像这样:
(
[2] => 0
[4] => 1
[6] => 2
[8] => 3
[10] => 4
)
*/
// $u 将保存交集的值
$u = [];
foreach (
$m as $v) {
if (isset(
$f[$v])) $u[] = $v;
}
print_r ($u);
$tend = microtime(true);
$time = $tend - $tstart;
echo
"Took $time";
?>

结果

数组
(
[1] => 2
[3] => 4
[5] => 6
[7] => 8
[9] => 10
)
耗时 4.7170009613037
(
[0] => 2
[1] => 4
[2] => 6
[3] => 8
[4] => 10
)
耗时 0.056024074554443

array_intersect:4.717
array_flip+isset:0.056
dml at nm dot ru
13 年前
当输入数组包含重复值时,内置函数会返回错误的结果。
以下代码能够正常工作

<?php
function array_intersect_fixed($array1, $array2) {
$result = array();
foreach (
$array1 as $val) {
if ((
$key = array_search($val, $array2, TRUE))!==false) {
$result[] = $val;
unset(
$array2[$key]);
}
}
return
$result;
}
?>
matang dot dave at gmail dot com
9 年前
在使用 `array_intersect` 函数时要注意值类型,因为该函数没有像 `in_array` 函数那样提供严格类型检查选项。

$array1 = array(true,2);
$array2 = array(1, 2, 3, 4, 5, 6);

var_dump(array_intersect($array1, $array2));

结果是
array(2) {
[0] => bool(true)
[1] => int(2)
}
Esfandiar -- e.bandari at gmail dot com
16 年前
关于数组并集:以下是一个更快的 `array_union($a, $b)` 版本

但这不是必需的!请见下文。

<?php
// $a = 1 2 3 4
$union = // $b = 2 4 5 6
array_merge(
$a,
array_diff($b, $a) // 5 6
); // $u = 1 2 3 4 5 6
?>

您使用 `$a + $b` 可以得到相同的结果。

注意:对于关联数组,`$a+$b` 和 `$b+$a` 的结果不同,我认为使用了 `array_diff_key`。

干杯,E
Malte
16 年前
扩展 Terry 于 2006 年 2 月 7 日 04:42 发布的帖子

如果您想将此函数用于有时包含相同值多次的数组,它不会检查这些值在第二个数组中是否存在次数与在第一个数组中相同。
因此,如果在第二个数组中找到该值,我会将其删除

<?php
$firstarray
= array(1, 1, 2, 3, 4, 1);
$secondarray = array(4, 1, 6, 5, 4, 1);

//array_intersect($firstarray, $secondarray): 1, 1, 1, 4

foreach ($firstarray as $key=>$value){
if (!
in_array($value,$secondarray)){
unset(
$firstarray[$key]);
}else{
unset(
$secondarray[array_search($value,$secondarray)]);
}
}

//$firstarray: 1, 1, 4

?>
nthitz at gmail dot com
18 年前
我做了一些测试,如果您知道数组的大致大小,那么这样做似乎会快得多: <?php array_intersect($smallerArray, $largerArray); ?> 其中 `$smallerArray` 是元素较少的数组。我只测试了长字符串,但我认为这在一定程度上是通用的。
theking2(at)king(dot)ma
7 个月前
更通用的参数检查

<?php
/**
* 检查请求中是否存在所有必需参数
*
* @param mixed $request 任何 $_GET, $_POST, $_REQUEST
* @param mixed $required 必需参数数组
* @return bool 如果所有必需参数都存在,则返回 true
*/
function check_params( array $request, array $required ): bool
{
$check = array_intersect( array_keys( $request ), $required );
return
count( $check ) === count( $required );
}
?>

使用方法
<?php
if( !check_params( $_GET, ['cust_id','prod_id'] ) {
header( "HTTP/1.1 400 Bad Request" );
echo
"Bad Request";
exit();
}
?>

如果 PHP 中已经有类似的功能,请告诉我...
t dot wiltzius at insightbb dot com
20 年前
我需要将一个具有关联键的数组与包含一些关联键的数组进行比较。基本上,我只想返回原始数组中的几个条目,而我想要的条目的键存储在另一个数组中。这非常简单(尽管解释起来很复杂),但我找不到比较值和键的合适函数。所以我写了这个相对简单的函数

<?php

function key_values_intersect($values,$keys) {
foreach(
$keys AS $key) {
$key_val_int[$key] = $values[$key];
}
return
$key_val_int;
}

$big = array("first"=>2,"second"=>7,"third"=>3,"fourth"=>5);
$subset = array("first","third");

print_r(key_values_intersect($big,$subset));

?>

它将返回

Array ( [first] => 2 [third] => 3 )
info at iridsystem dot it
9 年前
此函数能够根据包含出现顺序的另一个数组对数组进行排序。未找到的值将被转移到结果的末尾。
Questa funzione permette di ordinare i valori di un array ($tosort) basandosi sui valori contenuti in un secondo array ($base), i valori non trovati verranno posizionati alla fine dell'ordinamento senza un'ordine specifico.

<?
$base= array('one', 'two', 'three');

$tosort= array('a'=>'two', 'b'=>'three', 'c'=>'five', 'd'=>'one', 'and'=>'four', 'f'=>'one');

uasort($tosort, function($key1, $key2) use ($base) {
$a1=array_search($key1, $base);
$a2=array_search($key2, $base);

if ( $a1===false && $a2===false ) { return 0; }
else if ( $a1===false && $a2 !== false) { return 1; }
else if ( $a1!==false && $a2 === false) {return -1;}

if( $a1 > $a2 ) { return 1; }
else if ( $a1 < $a2 ) { return -1; }
else if ( $a1 == $a2 ) { return 0; }
});
var_dump($tosort);
/*
结果 $tosort
array
'd' => string 'one' (length=3)
'f' => string 'one' (length=3)
'a' => string 'two' (length=3)
'b' => string 'three' (length=3)
'c' => string 'five' (length=6)
'e' => string 'four' (length=7)
*/
Gabriel
?>
Yohann
14 年前
我使用 array_intersect 对数组进行任意排序

<?php
$a
= array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'height', 'nine', 'ten');
$b = array('four', 'one', 'height', 'five')
var_dump(array_intersect($a, $b);
?>

将输出

0 => 'one'
1 => 'four'
2 => 'five'
3 => 'height'

我希望这能有所帮助...
Oto Brglez
15 年前
如果你想对空数组进行交集操作,那么交集的结果将是空数组。

如果你想改变这个,我建议你这样做。
它只是“忽略”空数组。在循环之前使用第一个数组。

<?php

$a
= array();
$a[] = 1;
$a[] = 2;
$a[] = 3;

$b = array();
$b[] = 4;
$b[] = 5;
$b[] = 1;

$c = array();
$c[] = 1;
$c[] = 5;
$d = array();

$kb=array('a','b','c','d');

$out = $a;
foreach(
$kb as $k){
if(!empty(${
$k})) $out = array_intersect($out,${$k});
};
print_r($out);
// 结果是数组

// 结果是空数组
print_r(array_intersect($a,$b,$c,$d));

?>
terry(-at-)shuttleworths(-dot-)net
18 年前
我无法让 array_intersect 与两个包含相同对象的数组一起使用,所以我直接这样做

foreach ($firstarray as $key=>$value){
if (!in_array($value,$secondarray)){
unset($firstarray[$key]);
}
}

这样,$firstarray 就变成了交集。

看起来工作良好,速度也相当快。
tom p
18 年前
如果你在数据库字段中存储一串键,并且想要将它们与一个静态值数组进行匹配,这是一种无需循环就能快速实现的方法

<?

$vals = array("Blue","Green","Pink","Yellow");
$db_field = "0,2,3";

echo implode(", ", array_flip(array_intersect(array_flip($vals), explode(",", $db_field))));

// 将输出 "Blue, Pink, Yellow"

?>
ben at kazez dot com
20 年前
要检查数组 $a 是否是数组 $b 的子集,请执行以下操作

<?php
if(array_unique($b + $a) === $b)
//...
?>

实际上,PHP 应该有一个专门执行此操作的函数。但上面的例子可以正常工作。
karl at libsyn dot com
15 年前
给定一个表示 AND/OR 关系的多维数组(如下例所示),你可以使用带有 array_intersect() 的递归函数来查看另一个数组是否与该关系集匹配。

例如:array( array( 'red' ), array( 'white', 'blue' ) ) 表示“red OR ( white AND blue )”。array( 'red', array( 'white', 'blue' ) ) 也可以工作,顺便说一下。

如果我有数组( 'red' ),并且我想看看它是否与 AND/OR 数组匹配,我使用以下函数。它返回匹配的数组,
但如果只需要返回布尔值,也可以这样做

<?php
$needle
= array( array( 'red' ), array( 'white', 'blue' ) );
$haystack = array( 'red' );

function
findMatchingArray( $needle, $haystack ) {
foreach(
$needle as $element ) {
$test_element = (array) $element;
if(
count( $test_element ) == count( array_intersect( $test_element, $haystack ) ) ) {
return
$element;
}

}
return
false;
}
?>

很难描述我需要它做什么,但它确实起作用了。我不知道其他什么人需要这样的东西,但希望这能有所帮助。
anbolb at boltblue dot com
20 年前
这在测试数组中是否存在一系列可接受元素中的一个时也很有用。举个简单的例子,如果你期望查询字符串包含用户ID、订单ID或商品ID中的一个,你可以这样做来找出它是哪一个

<?php
$valid_ids
= array ('user_id', 'item_id', 'order_id');
if (
$id = current (array_intersect ($valid_ids, array_keys ($_GET))))
{
// 对其执行一些操作
}
else
// 错误 - 传递的 ID 无效,或者根本没有 ID
?>

…这对于构建 SQL 查询或其他情况下逐个测试可能过于笨拙的情况很有用。
Ehsan.Chavoshi.com
5 年前
我写了这个函数来递归地将数组键替换为数组值(翻转)并用定义的值填充值。它可以用于递归数组交集函数。

<?php
function array_values_to_keys_r($array, $fill_value = null)
{
$flipped = [];
foreach (
$array as $key => $value) {
if (
is_array($value)) {
$flipped [$key] = array_values_to_keys_r($value);
} else {
$flipped [$value] = $fill_value;
}
}
return
$flipped;
}
?>
david at audiogalaxy dot com
23 年前
请注意,array_intersect() 在比较数组元素时会考虑元素的类型。

如果 array_intersect() 似乎没有工作,请使用 var_dump() 检查您的输入,以确保您没有尝试将整数数组与字符串数组进行交集。
caffinated
11 年前
如果您正在寻找一种相对简单的方法来严格递归地交集键和值,而不会重新排序数组键,这里有一个简单的递归函数

<?php
function array_intersect_recursive($array1, $array2)
{
foreach(
$array1 as $key => $value)
{
if (!isset(
$array2[$key]))
{
unset(
$array1[$key]);
}
else
{
if (
is_array($array1[$key]))
{
$array1[$key] = array_intersect_recursive($array1[$key], $array2[$key]);
}
elseif (
$array2[$key] !== $value)
{
unset(
$array1[$key]);
}
}
}
return
$array1;
}
?>
gary
15 年前
我写了这个来解决我在获取字符串交集而不是数组时遇到的问题,因为 PHP 中没有这样的函数。

<?php
function matched_main_numbers($string, $string2)
{
$string = "04 16 17 20 29";
$arr1 = explode(" ", $string);

$string2 = "45 34 04 29 16";
$arr2 = explode(" ", $string2);

$array = array_intersect($arr1, $arr2);
$comma_separated = implode($array);

$str = $comma_separated;

$balls = "$comma_separated";
$matched_balls = chunk_split($balls,2," ");
$matched_balls =" $matched_balls";

$number_of_matched_main_balls = strlen($str);
$number_of_matched_main_balls = ($number_of_matched_main_balls/2);
$numbers = "You matched $number_of_matched_main_balls main balls";

return
$numbers;

}
?>
meihao at 126 dot com
10 年前
<?php
$a
=array(1,2,'3',4);
$b=array('1',2,3);

var_dump($a,$b);

result:
array (
size=3)
0 => int 1
1
=> int 2
2
=> string '3' (length=1)

?>
Alessandro Ranellucci alex at primafila dot net
21 年前
array_intersect($array1, $array2);
返回与以下相同的结果
array_diff($array1, array_diff($array1, $array2));
189780 at gmail dot com
14 年前
实际上,array_intersect() 会找到重复的值,这是我的方法,它比内置函数 array_intersect() 快 5 倍。试试看。

<?php
function my_array_intersect($a,$b)
{
for(
$i=0;$i<sizeof($a);$i++)
{
$m[]=$a[$i];
}
for(
$i=0;$i<sizeof($a);$i++)
{
$m[]=$b[$i];
}
sort($m);
$get=array();
for(
$i=0;$i<sizeof($m);$i++)
{
if(
$m[$i]==$m[$i+1])
$get[]=$m[$i];
}
return
$get;
}
?>

Barış ÇUHADAR
[email protected]
Mike Block
11 年前
我测试了一些 array_intersect 的用法,难以置信它有多慢。这个方法没有那么复杂,但可以处理大多数情况,并且速度更快

<?php
/**
检查两个数组并返回具有匹配键的交集数组(忽略重复键)
*/
function simple_array_intersect($a,$b) {
$a_assoc = $a != array_values($a);
$b_assoc = $b != array_values($b);
$ak = $a_assoc ? array_keys($a) : $a;
$bk = $b_assoc ? array_keys($b) : $b;
$out = array();
for (
$i=0;$i<sizeof($ak);$i++) {
if (
in_array($ak[$i],$bk)) {
if (
$a_assoc) {
$out[$ak[$i]] = $a[$ak[$i]];
} else {
$out[] = $ak[$i];
}
}
}
return
$out;
}

?>

你可以用这个来试试

<?php
// 创建一个大型数组(简单)
$first = array();
for (
$i=500;$i<500000;$i++) {
$first[] = $i;
}
// 创建一个较小的数组(关联)
$second = array();
for (
$i=499990;$i<500000;$i++) {
$second[$i] = rand();
}
echo
microtime(true)."\n";
// 内置函数
print_r(array_intersect($first,$second));
echo
microtime(true)."\n";
// 优先使用简单数组作为匹配
print_r(simple_array_intersect($first,$second));
echo
microtime(true)."\n";
// 优先使用关联键进行匹配
print_r(simple_array_intersect($second,$first));
echo
microtime(true)."\n";

?>
zoolyka at gmail dot com
5 年前
如果你必须对唯一值的数组进行交集运算,那么使用 array_intersect_key 大约快 20 倍,只需要翻转数组的键值对,然后再次翻转结果。

<?php

$one
= range(1, 250000);
$two = range(50000, 150000);

$start = microtime(true);

$intersection = array_intersect($one, $two);

echo
"Did it in ".( microtime(true) - $start )." seconds.\n";

$start = microtime(true);

$intersection = array_flip(array_intersect_key(array_flip($one), array_flip($two)));

echo
"Did it in ".( microtime(true) - $start )." seconds.\n";

?>

Did it in 0.89163708686829 seconds.
Did it in 0.038213968276978 seconds.
ram
5 年前
$x = array('[email protected]', 'ram', '[email protected]');
$y = array('1231231231');
$result=array_intersect($x,$z);
$res = array_intersect($y, $z);
jake
7 年前
还要注意,即使没有严格模式开关,false 也不会匹配 0

array_intersect([false], [0]) == [];

即使在 PHP 7.1 中也是如此
To Top