PHPのお勉強!

PHP TOP

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 の場合のみ等しいとみなされます。言い換えると、文字列表現が同じ場合となります。

参考

add a note

User Contributed Notes 33 notes

up
173
stuart at horuskol dot co dot uk
16 years ago
A clearer example of the key preservation of this function:

<?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));

?>

yields the following:

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

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

This makes it important to remember which way round you passed the arrays to the function if these keys are relied on later in the script.
up
6
theking at king dot ma
2 years ago
I use array_intersect for a quick check of $_GET parameters;

<?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();
}
?>

the file will die with a 400 error if cust_id or prod_id or both are missing from $_GET. But i could be used on $_POST and $_REQUEST as well obviously.
up
4
Anonymous
3 years ago
array_intersect use Value, not callback
array_uintersect use Value, callback receives Value
array_intersect_key use Key, not callback
array_intersect_ukey use Key, callback receives Key
array_intersect_assoc use Both, not callback
array_intersect_uassoc use Both, callback receives Key ONLY
array_uintersect_assoc use Both, callback receives Value ONLY
array_uintersect_uassoc use Both, One callback receives the Key, the other receives the Value.
up
76
Niels
18 years ago
Here is a 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
?>
up
26
sapenov at gmail dot com
19 years ago
If you need to supply arbitrary number of arguments
to array_intersect() or other array function,
use following function:

$full=call_user_func_array('array_intersect', $any_number_of_arrays_here);
up
21
Shawn Pyle
15 years ago
array_intersect handles duplicate items in arrays differently. If there are duplicates in the first array, all matching duplicates will be returned. If there are duplicates in any of the subsequent arrays they will not be returned.

<?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)
?>
up
11
yuval at visualdomains dot com
9 years ago
Using isset to achieve this, is many times faster:

<?php

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

// Use array_intersect to return all $m values that are also in $s
$tstart = microtime(true);
print_r (array_intersect($m,$s));
$tend = microtime(true);
$time = $tend - $tstart;
echo
"Took $time";

// Use array_flip and isset to return all $m values that are also in $s
$tstart = microtime(true);
$f = array_flip($s);
/* $f now looks like this:
(
[2] => 0
[4] => 1
[6] => 2
[8] => 3
[10] => 4
)
*/
// $u will hold the intersected values
$u = [];
foreach (
$m as $v) {
if (isset(
$f[$v])) $u[] = $v;
}
print_r ($u);
$tend = microtime(true);
$time = $tend - $tstart;
echo
"Took $time";
?>

Results:

Array
(
[1] => 2
[3] => 4
[5] => 6
[7] => 8
[9] => 10
)
Took 4.7170009613037
(
[0] => 2
[1] => 4
[2] => 6
[3] => 8
[4] => 10
)
Took 0.056024074554443

array_intersect: 4.717
array_flip+isset: 0.056
up
16
blu at dotgeek dot org
20 years ago
Note that array_intersect and array_unique doesnt work well with multidimensional arrays.
If you have, for example,

<?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');

?>

and wants to know if the same person bought the same thing today and yesterday and use array_intersect($orders_today, $orders_yesterday) you'll get as result:

<?php

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

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

)

?>

but we can get around that by serializing the inner arrays:
<?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'));

?>

so that array_map("unserialize", array_intersect($orders_today, $orders_yesterday)) will return:

<?php

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

)

?>

showing us who bought the same thing today and yesterday =)

[]s
up
8
dml at nm dot ru
13 years ago
The built-in function returns wrong result when input arrays have duplicate values.
Here is a code that works correctly:

<?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;
}
?>
up
3
matang dot dave at gmail dot com
9 years ago
Take care of value types while using array_intersect function as there is no option for strict type check as in in_array function.

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

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

result is :
array(2) {
[0] => bool(true)
[1] => int(2)
}
up
4
Esfandiar -- e.bandari at gmail dot com
16 years ago
Regarding array union: Here is a faster version array_union($a, $b)

But it is not needed! See below.

<?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
?>

You get the same result with $a + $b.

N.B. for associative array the results of $a+$b and $b+$a are different, I think array_diff_key is used.

Cheers, E
up
1
Malte
16 years ago
Extending the posting by Terry from 07-Feb-2006 04:42:

If you want to use this function with arrays which have sometimes the same value several times, it won't be checked if they're existing in the second array as much as in the first.
So I delete the value in the second array, if it's found there:

<?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

?>
up
1
nthitz at gmail dot com
18 years ago
I did some trials and if you know the approximate size of the arrays then it would seem to be a lot faster to do this <?php array_intersect($smallerArray, $largerArray); ?> Where $smallerArray is the array with lesser items. I only tested this with long strings but I would imagine that it is somewhat universal.
up
1
theking2(at)king(dot)ma
1 year ago
A more generic parameter checking:

<?php
/**
* Check if all required parameters are present in the request
*
* @param mixed $request any of $_GET, $_POST, $_REQUEST
* @param mixed $required array of required parameters
* @return bool true if all required parameters are present
*/
function check_params( array $request, array $required ): bool
{
$check = array_intersect( array_keys( $request ), $required );
return
count( $check ) === count( $required );
}
?>

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

Let me know if something is build in PHP already...
up
1
t dot wiltzius at insightbb dot com
20 years ago
I needed to compare an array with associative keys to an array that contained some of the keys to the associative array. Basically, I just wanted to return only a few of the entries in the original array, and the keys to the entries I wanted were stored in another array. This is pretty straightforward (although complicated to explain), but I couldn't find a good function for comparing values to keys. So I wrote this relatively straightforward one:

<?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));

?>

This will return:

Array ( [first] => 2 [third] => 3 )
up
1
Yohann
14 years ago
I used array_intersect in order to sort an array arbitrarly:

<?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);
?>

will output:

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

i hope this can help...
up
0
zoolyka at gmail dot com
6 years ago
If you have to intersect arrays of unique values then using array_intersect_key is about 20 times faster, just have to flip the key value pairs of the arrays, then flip the result again.

<?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.
up