【问题标题】:Intersecting multidimensional array of varying size不同大小的相交多维数组
【发布时间】:2010-01-07 13:14:18
【问题描述】:

我有一个如下所示的多维数组:

Array
(
[0] => Array
    (
        [0] => Array
            (
                [id] => 3
            )

        [1] => Array
            (
                [id] => 1
            )

        [2] => Array
            (
                [id] => 2
            )

        [3] => Array
            (
                [id] => 5
            )

        [4] => Array
            (
                [id] => 4
            )

    )

[1] => Array
    (
        [0] => Array
            (
                [id] => 1
            )

        [1] => Array
            (
                [id] => 3
            )

        [2] => Array
            (
                [id] => 4
            )

        [3] => Array
            (
                [id] => 5
            )

    )

[2] => Array
    (
        [0] => Array
            (
                [id] => 3
            )

    )

)

我需要找到一种方法来返回相交值。在这种情况下,那将是

[id] => 3

数组的长度可能不同,所以我不能只使用array_intersect()。

【问题讨论】:

    标签: php multidimensional-array


    【解决方案1】:

    如果你的数组只包含整数,这会很简单,但由于它们包含另一个数组,它会变得有点复杂。但是应该这样做:

    function custom_intersect($arrays) {
        $comp = array_shift($arrays);
        $values = array();
    
        // The other arrays are compared to the first array:
        // Get all the values from the first array for comparison
        foreach($comp as $k => $v) {
            // Set amount of matches for value to 1.
            $values[$v['id']] = 1;
        }
    
        // Loop through the other arrays
        foreach($arrays as $array) {
            // Loop through every value in array
            foreach($array as $k => $v) {
                // If the current ID exists in the compare array
                if(isset($values[$v['id']])) {
                    // Increase the amount of matches
                    $values[$v['id']]++;
                }
            }
        }
    
        $result = array();
    
        // The amount of matches for certain value must be
        // equal to the number of arrays passed, that's how
        // we know the value is present in all arrays.
        $n = count($arrays) + 1;
        foreach($values as $k => $v) {
            if($v == $n) {
                // The value was found in all arrays,
                // thus it's in the intersection
                $result[] = $v;
            }
        }
        return $result;
    }
    

    用法:

    $arrays = array(
        array(array('id' => 3), array('id' => 1), array('id' => 2), array('id' => 5), array('id' => 4)),
        array(array('id' => 1), array('id' => 3), array('id' => 4), array('id' => 5)),
        array(array('id' => 3))
    );
    
    print_r(custom_intersect($arrays));
    

    结果:

    Array
    (
        [0] => 3
    )
    

    此功能并不完美:如果您在一个数组中有重复的 ID,它将无法工作。这将需要更多代码来首先使数组值唯一,但这可能适用于您的情况。

    【讨论】:

      【解决方案2】:

      您可以使用array_uintersect() 使用自定义比较函数获取数组的交集。不过,您必须使用 call_user_func_array() 调用它,因为它希望每个数组都作为单独的参数:

      //build list of parameters for array_uintersect()
      $params = array_merge($input, array('compare_func'));
      
      $result = call_user_func_array('array_uintersect', $params);
      
      function compare_func($a, $b) {
          return $a['id'] - $b['id'];   
      }
      

      你不能简单地用call_user_func_array() 来调用array_intersect(),因为它似乎是通过比较它们的字符串表示来比较数组(它总是'Array')。

      【讨论】:

        【解决方案3】:
        $a = array(4,3);
        $b = array(4,3,2,1);
        $c = array(1,2,3,4,5);
        $d = array(5,4,3);
        
        $array = array($a,$b,$c,$d);
        
        for ($i=0; $i<count($array); $i++){
            if ($i==0){
                $array2 = $array[$i];
            } else {
                $array2 = array_intersect($array2, $array[$i]);
            }
        }
        
        print_r($array2);`
        

        结果:

        3,4

        【讨论】:

          【解决方案4】:

          如php.net网站的其中一个cmet中提到的(array_intersect函数)。

          $a = array(1,2,3,4,5,2,6,1);  /* repeated elements --> $a is not a set */
          $b = array(0,2,4,6,8,5,7,9,2,1);  /* repeated elements --> $b is not a set */
          
          $ua = array_merge(array_unique($a));  /* now, $a is a set */
          $ub = array_merge(array_unique($b));  /* now, $b is a set */
          
          $intersect = array_merge(array_intersect($ua,$ub));
          

          这将返回这个数组:

          Array
          (
              [0] => 1
              [1] => 2
              [2] => 4
              [3] => 5
              [4] => 6
          )
          

          【讨论】:

          • 不幸的是,这在这种情况下不起作用,因为数组包含设置了键“id”的数组。您仅适用于具有标量值的数组 - 这需要自定义函数。
          猜你喜欢
          • 2013-06-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多