多维关联数组交集php

Posted

技术标签:

【中文标题】多维关联数组交集php【英文标题】:Multidimensional associative array intersection php 【发布时间】:2012-08-29 06:12:04 【问题描述】:

我有两个多维数组

$array1 = Array (
   [a1] => Array  (
           [a_name] => aaaaa
           [a_value] => aaa
         )

   [b1] => Array (
           [b_name] => bbbbb
           [b_value] => bbb
       )
   [c1] => Array (
           [c_name] => ccccc
           [c_value] => ccc
       )

 )

$array2 = Array (
     [b1] => Array (
           [b_name]=> zzzzz
         )
  )

我想要$array1$array2 的键的交集。结果必须来自$array1

【问题讨论】:

array_intersect_key 不做多维相交 它在上相交,值是数组没关系。 【参考方案1】:
function recursive_array_intersect_key(array $array1, array $array2) 
    $array1 = array_intersect_key($array1, $array2);
    foreach ($array1 as $key => &$value) 
        if (is_array($value) && is_array($array2[$key])) 
            $value = recursive_array_intersect_key($value, $array2[$key]);
        
    
    return $array1;

演示here.

【讨论】:

非常感谢@deceze,这正是我所需要的。你太棒了。 第一个是索引数组,第二个子数组是关联数组怎么办? 当值是这样的数组时,您还需要检查第二个参数是否为数组以防止类型错误(将非数组值发送回函数):'if (is_array ($value) && is_array($array2[$key])) ´ 嗨@deceze,如何添加 $array2 两者都匹配和不匹配到 $array2【参考方案2】:
$output = array_intersect_key($array1, $array2);

【讨论】:

【参考方案3】:

php中二维关联数组交集的演示

守则:

<?php
    function compare_states($a1, $a2)
        $diff1 = strcasecmp($a1['state_id'], $a2['state_id']);
        $diff2 = strcasecmp($a1['state_name'], $a2['state_name']);
        if ($diff1 != 0) return $diff1;
        if ($diff2 != 0) return $diff2;
        return 0;
    
    function calculate_intersection($a1, $a2)
        return array_uintersect($a1, $a2, 'compare_states');
    
?>

如何运行:

<?php
    $a = Array(Array("state_id"=>14, "state_name"=>"Illinois"));
    $b = Array(Array("state_id"=>14, "state_name"=>"Illinois"));
    $new = calculate_intersection($a, $b);
    print_r($a);
    //in this simple case, the intersection is equivalent to $a.
    $a = Array(Array("state_id"=>14, "state_name"=>"Illinois"));
    $b = Array(Array("state_id"=>14, "state_name"=>"Foobar"));
    $new = calculate_intersection($a, $b);
    print_r($a);
    //in this case, the intersection is empty.
?>

单元测试以证明上述代码按设计工作:

$a = Array();
$b = Array();
$new = calculate_intersection($a, $b);
print "\nGroup1\n";
print ((count($new) == count($a) && count($a) == count($b)) ? "." : "FAIL");
print ((count($new) == 0) ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>14, "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>14, "state_name"=>"Illinois"));
$new = calculate_intersection($a, $b);
print "\nGroup2\n";
print ((count($new) == count($a) && count($a) == count($b)) ? "." : "FAIL");
print ((count($new) == 1) ? "." : "FAIL");
print (($new[0]['state_id'] == 14 ? "." : "FAIL"));
print (($new[0]['state_name'] == "Illinois" ? "." : "FAIL"));
//==============================================
print "\nGroup3\n";
$a = Array(Array("state_id"=>14, "state_name"=>"Illinois"), Array("state_id"=> "22", "state_name"=>"Massachusetts"));
$b = Array(Array("state_id"=>14, "state_name"=>"Illinois"), Array("state_id"=> "22", "state_name"=>"Massachusetts"));
$new = calculate_intersection($a, $b);
print ((count($new) == count($a) && count($a) == count($b)) ? "." : "FAIL");
print (($new[0]['state_id'] == 14 ? "." : "FAIL"));
print (($new[0]['state_name'] == "Illinois" ? "." : "FAIL"));
print (($new[1]['state_id'] == 22 ? "." : "FAIL"));
print (($new[1]['state_name'] == "Massachusetts" ? "." : "FAIL"));
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>"22", "state_name"=>"Massachusetts"));
$new = calculate_intersection($a, $b);
print "\nGroup5\n";
print ((count($new) == 0) ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>"14", "state_name"=>"Illinois"), Array("state_id"=>"22", "state_name"=>"Massachusetts"));
$new = calculate_intersection($a, $b);
print "\nGroup6\n";
print ((count($new) == 1) ? "." : "FAIL");
print (($new[0]['state_id'] == 14) ? "." : "FAIL");
print (($new[0]['state_name'] == "Illinois") ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>"22", "state_name"=>"Massachusetts"), Array("state_id"=>"14", "state_name"=>"Illinois"));
$new = calculate_intersection($a, $b);
print "\nGroup7\n";
print ((count($new) == 1) ? "." : "FAIL");
print (($new[0]['state_id'] == 14) ? "." : "FAIL");
print (($new[0]['state_name'] == "Illinois") ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>"22", "state_name"=>"Massachusetts"), Array("state_id"=>"14", "state_name"=>"Fromulate"));
$new = calculate_intersection($a, $b);
print "\nGroup8\n";
print ((count($new) == 0) ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"), Array("state_id"=>"14", "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>"14", "state_name"=>"Illinois"), Array("state_id"=>"14", "state_name"=>"Illinois"));
$new = calculate_intersection($a, $b);
print "\nGroup9\n";
print ((count($new) == 2) ? "." : "FAIL");
print (($new[0]['state_id'] == 14) ? "." : "FAIL");
print (($new[0]['state_name'] == "Illinois") ? "." : "FAIL");
print (($new[1]['state_id'] == 14) ? "." : "FAIL");
print (($new[1]['state_name'] == "Illinois") ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"), Array("state_id"=>"22", "state_name"=>"Massachusetts"));
$b = Array(Array("state_id"=>"22", "state_name"=>"Massachusetts"), Array("state_id"=>"14", "state_name"=>"Illinois"));
$new = calculate_intersection($a, $b);
print "\nGroup7\n";
print ((count($new) == 2) ? "." : "FAIL");
print (($new[0]['state_id'] == 14) ? "." : "FAIL");
print (($new[0]['state_name'] == "Illinois") ? "." : "FAIL");
print (($new[1]['state_id'] == 22) ? "." : "FAIL");
print (($new[1]['state_name'] == "Massachusetts") ? "." : "FAIL");
?>

上面的代码打印:

eric@dev $ php a.php
Group1
..
Group2
....
Group3
.....
Group5
.
Group6
...
Group7
...
Group8
.
Group9
.....
Group7
.....

所有的点表示一切都通过了。

这段代码处理什么情况?

    两个数组都是空的。交叉口是空的。 一个是空的,另一个是物品。交叉口是空的。 两个数组具有相同的项,设置:1 和设置:n。交集相当于第一个数组。 这两个数组是相同的,除了改组。交集相当于第一个数组。 除了 state_name 在每种情况下不同,并且 state_id 相同之外,这些数组都是相同的。路口是空的。 数组 a 有 b 不常见的项目,b 共有的项目。数组 b 有 a 不常见的项目和 A 共有的项目。交集是 a 和 b 共有的项目。

不能做什么:

它不会测试空值/未定义/不同深度数组,也不会测试 2 层或更多层深的数组。如果数据类型被交换,将字符串与整数进行比较,或者将浮点数与八进制进行比较,它可能会失败。很难让 PHP 正确地做相等。 http://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/

尽你所能尝试在数据库中完成这项工作,在 PHP 中完成这项工作会吹响号角来召唤失败的鲸鱼。它效率低下,因此您最好不要对超过几百个项目进行操作。在意想不到的情况下,左戳你会让你感到惊讶,而且很难阅读/理解它在幕后所做的事情。

【讨论】:

【参考方案4】:

我认为你应该检查 $array2[$key] 是否也是一个数组。

function recursive_array_intersect_key(array $array1, array $array2) 
    $array1 = array_intersect_key($array1, $array2);
    foreach ($array1 as $key => &$value) 
        if (is_array($value) && is_array($array2[$key])) 
            $value = recursive_array_intersect_key($value, $array2[$key]);
        
    
    return $array1;

【讨论】:

以上是关于多维关联数组交集php的主要内容,如果未能解决你的问题,请参考以下文章

PHP填充多维关联数组 - 最简单的方法

如何从 PHP 中的多维关联数组中删除项目

使用带有 sql 的键值对搜索 php 多维关联数组,例如 '%LIKE%' 构造

C# 中的多维关联数组

如果两个值匹配,则从 php 中的多维关联数组中删除重复项

php多维数组自定义排序 uasort()