【问题标题】:How to get all possible intersections of multiple multidimensional arrays?如何获得多个多维数组的所有可能交集?
【发布时间】:2015-12-12 12:27:18
【问题描述】:

我在 PHP 中有两个这样的数组:

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

现在我想得到这两个多维数组的所有可能的交集。意味着我总共会得到 4 个数组:

  • $array1[0] & $array2[0]
  • $array1[1] & $array2[0]
  • $array1[0] & $array2[1]
  • $array1[1] & $array2[1]

我可以使用array_intersect() 从一维数组中获取交集。但是我怎样才能得到多个多维数组的所有可能的交集呢?

【问题讨论】:

    标签: php arrays multidimensional-array array-intersect


    【解决方案1】:

    这里我们创建了一个包含所有数组组合的数组,因此我们以后可以取这些数组的交集。

    数组组合

    首先我们需要创建所有可能的数组组合。即:

    carray 1 * carray 2 * ... * carray n

    "c" 只表示数组的count()

    因此,在您的具体示例中,它将是:

    c数组 1 * c数组 2 => 2 * 2 => 4 个组合

    现在我们需要获取所有这些组合并将它们放入一个数组中。为此,我们从一个空的 $combinations 数组开始。然后我们循环遍历数组中的所有组合并将下一个数组合并到其中,直到我们获得所需的组合长度,在本例中为我们拥有的数组数量。

    举个例子:

    Array with the elements (Empty array is '[]'):
    
    [
        [[1, 3, 4], [1, 4]],     //array 1
        [[5, 4, 3, 2], [5, 3]],  //array 2
    ]
    

               1* combination array    2* new array     //↓new combinations
                        ↓                   ↓           //↓for the next iteration
                                                        │
    array NAN*:
    
        Combinations:
                      - []                              │  -> []
                                                           │
    array 1:            ┌──────────────────────────────────┘
                        │                       
        Combinations:   v                       
                      - []             + [1, 3, 4]      │  -> [[1, 3, 4]]  
                      - []             + [1, 4]         │  -> [[1, 4]]   
                                                           │
    array 2:            ┌──────────────────────────────────┘
                        │                       
        Combinations:   v                       
                      - [[1, 3, 4]]    + [5, 4, 3, 2]   │  -> [[1, 3, 4], [5, 4, 3, 2]]
                      - [[1, 3, 4]]    + [5, 3]         │  -> [[1, 3, 4], [5, 3]]
                      - [[1, 4]]       + [5, 4, 3, 2]   │  -> [[1, 4], [5, 4, 3, 2]]
                      - [[1, 4]]       + [5, 3]         │  -> [[1, 4], [5, 3]] 
                                                        //↑ All combinations here
    

    * NAN:不是数字

    正如您在上面的示例中看到的那样,我们现在拥有所有组合,其长度与我们拥有的所有数组的数量相同(4 个组合,长度为 2 个元素)。

    如上例中获取组合的代码为:

    //for循环确保我们得到每个组合所需的长度
    //(我们拥有的数组数量。这里是2)
    for ($count = 0, $length = count($data); $count //1* 组合数组
    
            foreach ($data[$count] as $v2) //2* 新数组
                $tmp[] = array_merge($v1, [$v2]); //创建新的组合
    
        }
    
        $组合 = $tmp; //为下一次迭代分配新的组合
    
    }
    

    在您的具体示例中生成此数组:

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

    数组交集

    现在我们已经有了所有组合,我们可以使用 array_map() 遍历组合数组并获得每个组合的 array_intersect()。而且由于我们不知道需要多少个数组进行交集,所以我们只使用call_user_func_array(),例如

    $intersections = array_map(function($v){
        //intersection of each combination, which we created
        return call_user_func_array("array_intersect", $v);
    }, $combinations);
    

    完整代码:

    <?php
    
        $array1 = [[1, 3, 4], [1, 4]];
        $array2 = [[5, 4, 3, 2], [5, 3]];
    
    
        function getIntersections($data = []) {
            $combinations = [[]];
    
            for ($count = 0, $length = count($data); $count < $length; $count++) {
                $tmp = [];
                foreach ($combinations as $v1) {
                    foreach ($data[$count] as $v2)
                        $tmp[] = array_merge($v1, [$v2]);
                }
                $combinations = $tmp;
            }
    
            $intersections = array_map(function($v){
                return call_user_func_array("array_intersect", $v);
            }, $combinations);
    
            return $intersections;
    
        }
    
        $intersections = getIntersections([$array1, $array2]);
        print_r($intersections);
    
    ?>
    

    输出:

    Array
    (
        [0] => Array  //Intersection of: [1, 3, 4] && [5, 4, 3, 2]
            (
                [1] => 3
                [2] => 4
            )
    
        [1] => Array  //Intersection of: [1, 3, 4] && [5, 3]
            (
                [1] => 3
            )
    
        [2] => Array  //Intersection of: [1, 4] && [5, 4, 3, 2]
            (
                [1] => 4
            )
    
        [3] => Array  //Intersection of: [1, 4] && [5, 3]
            (
            )
    
    )
    

    【讨论】:

      【解决方案2】:

      这个foreach 正在解决我的问题

      $array1= array(array("1","3","4"),array("1","4"));
      $array2= array(array("5","4","3","2"),array("5","3"));
      $result = array();
      echo "<pre>";
      foreach($array1 as $array1)
      {
          foreach($array2 as $array3)
          {
              print_r($array3);
              $result[] = array_intersect($array1,$array3);
          }
      }
      
      print_r($result);
      

      如果你有更好的解决方案,请改进它

      【讨论】:

        猜你喜欢
        • 2013-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-10
        • 2020-03-01
        • 2012-11-25
        • 2012-06-05
        • 2018-10-18
        相关资源
        最近更新 更多