2017-01-08 16:13

# 检查数组是否在两个多维数组中

I have two multidimensional arrays:

Haystack

``````\$haystack = array (
0 => array (
"child_element_id" => 11
),
1 => array (
"child_element_id" => 12
),
2 => array (
"child_element_id" => 13
)
)
``````

Needle

`````` \$needle = array (
0 => array (
"child_element_id" => 12
),
1 => array (
"child_element_id" => 13
)
)
``````

I want to check if all the key values from array "Needle" exists in the array "Haystack". What's the best practice for this? Thank you!

• 点赞
• 写回答
• 关注问题
• 收藏
• 复制链接分享
• 邀请回答

#### 3条回答

• Pretty easy using `in_array()` since needle can be an array:

``````\$found = 0;
foreach(\$needle as \$array) {
if(in_array(\$array, \$haystack, true)) {
\$found++;
}
}
if(\$found === count(\$needle)) {
echo 'all needles were found in haystack';
}
``````

Or maybe:

``````\$found = true;
foreach(\$needle as \$array) {
if(!in_array(\$array, \$haystack, true)) {
\$found = false;
break;
}
}
if(\$found) {
echo 'all needles were found in haystack';
}
``````

You could even use `array_search()` as you can use an array for needle as well, no need to run two loops.

Using `serialize()`:

``````if(count(array_map('unserialize',
array_intersect(array_map('serialize', \$needle),
array_map('serialize',\$haystack)))) == count(\$needle))
{
echo 'all needles were found in haystack';
}
``````
• `serialize()` the inner arrays of both arrays and compute the intersection (common inner arrays)
• `unserialize()` the result and compare the `count()` with the count of `\$needle`
点赞 评论 复制链接分享
• douwen3500 4年前

almost a solution:
@shalvah gave a good starting point. However, in the suggested solution he forgot to loop over the elements of the `\$needle` array like shown below:

``````function array_in_array(\$neearr,\$haystack) {
foreach (\$neearr as \$needle){
foreach (\$haystack as \$array) {
//check arrays for equality
if(count(\$needle) == count(\$array)) {
\$needleString = serialize(\$needle);
\$arrayString = serialize(\$array);
echo "\$needleString||\$arrayString<br>";
if(strcmp(\$needleString, \$arrayString) == 0 ) return true;
}
return false;
}
}
}
``````

But even so is this not completely "water tight". In cases where elements of the "needle" arrays appear in a different order (sequence) the `serialze()`-function will produce differing strings and will lead to false negatives, like shown in the exampe below:

``````\$hay=array(array('a'=>'car','b'=>'bicycle'),
array('a'=>'bus','b'=>'truck'),
array('a'=>'train','b'=>'coach'));

\$nee1=array(array('a'=>'car','b'=>'bicycle'),
array('a'=>'train','b'=>'coach'));

\$nee2=array(array('b'=>'bicycle','a'=>'car'),  // different order of elements!
array('a'=>'train','b'=>'coach'));

echo array_in_array(\$nee1,\$hay); // true
echo array_in_array(\$nee2,\$hay); // false (but should be true!)
``````

a slightly better solution
This problem can be solved by first sorting (`ksort()`: sort by key value) all the elements of all the "needle" arrays before `serialize`-ing them:

``````function array_in_array(\$neearr,\$haystack) {
\$haystackstrarr = array_map(function(\$array){ksort(\$array);return serialize(\$array);},\$haystack);
foreach (\$neearr as \$needle){
ksort(\$needle);
\$needleString = serialize(\$needle);
foreach (\$haystackstrarr as \$arrayString){
if(strcmp(\$needleString, \$arrayString) == 0 ) return true;
}
return false;
}
}

echo array_in_array(\$nee1,\$hay); // true
echo array_in_array(\$nee2,\$hay); // true
``````
点赞 评论 复制链接分享
• dpgjci27392 4年前

You could use this function:

``````function array_in_array(array \$needle, array \$haystack) {
foreach(\$needle as \$nearr) {
foreach (\$haystack as \$array) {
//check arrays for equality
if(count(\$needle) == count(\$array)) {
\$needleString = serialize(\$needle);
\$arrayString = serialize(\$array);
if(strcmp(\$needleString, \$arrayString) == 0 )
return true;
}
}
return false;
}
``````
点赞 评论 复制链接分享