【问题标题】:Merging arrays recursively PHP递归合并数组PHP
【发布时间】:2017-07-19 04:17:12
【问题描述】:

我正在使用这个函数递归合并两个数组:

function array_merge_recursive_distinct(array &$array1, array &$array2) {

  $merged = $array1;

  foreach($array2 as $key => &$value) {

      if(is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {

          $merged[$key] = array_merge_recursive_distinct($merged[$key], $value);

      } else {

          $merged[$key] = $value;
      }
  }

  return $merged;
}

为了使用此功能,我正在执行以下步骤:

  • 声明一个空数组 $outArray = array();
  • 做一个while循环来收集我需要的信息
    • 在 while 循环期间,我调用 array_merge_recursive_distinct 函数以递归方式填充空数组

然而,最终的数组只包含它在最后一个 while 循环中收集到的最后信息。我试图找到一个解决方案,但直到现在我还没有成功。我究竟做错了什么? 递归函数在 while 循环期间获取所有信息(我已经在递归函数中打印了输入数组),但它似乎一遍又一遍地覆盖合并的数组。

谢谢

【问题讨论】:

    标签: php arrays recursion merge


    【解决方案1】:

    CakePHP 有一个名为 Hash 的好类,它实现了一个名为 merge() 的方法,它可以满足您的需要

    /**
     * This function can be thought of as a hybrid between PHP's `array_merge` and `array_merge_recursive`.
     *
     * The difference between this method and the built-in ones, is that if an array key contains another array, then
     * Hash::merge() will behave in a recursive fashion (unlike `array_merge`). But it will not act recursively for
     * keys that contain scalar values (unlike `array_merge_recursive`).
     *
     * Note: This function will work with an unlimited amount of arguments and typecasts non-array parameters into arrays.
     *
     * @param array $data Array to be merged
     * @param mixed $merge Array to merge with. The argument and all trailing arguments will be array cast when merged
     * @return array Merged array
     * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::merge
     */
    function merge_arrays_recursivelly(array $data, $merge) { // I changed the function name from merge to  merge_arrays_recursivelly
        $args = array_slice(func_get_args(), 1);
        $return = $data;
    
        foreach ($args as &$curArg) {
            $stack[] = array((array) $curArg, &$return);
        }
        unset($curArg);
    
        while (!empty($stack)) {
            foreach ($stack as $curKey => &$curMerge) {
                foreach ($curMerge[0] as $key => &$val) {
                    if (!empty($curMerge[1][$key]) && (array) $curMerge[1][$key] === $curMerge[1][$key] && (array) $val === $val) {
                        $stack[] = array(&$val, &$curMerge[1][$key]);
                    } elseif ((int) $key === $key && isset($curMerge[1][$key])) {
                        $curMerge[1][] = $val;
                    } else {
                        $curMerge[1][$key] = $val;
                    }
                }
                unset($stack[$curKey]);
            }
            unset($curMerge);
        }
        return $return;
    }
    

    https://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::merge

    Hash::merge source code

    【讨论】:

      【解决方案2】:

      也许这样的东西可能会很方便。

      function array_merge_recursive_distinct(array &$array1, array &$array2) {
          $merged = array_merge($array1,$array2);
          asort($merged);
          $merged = array_values(array_unique($merged));
          return $merged;
      }
      $array1 = [];
      $array2 = [1,2,3,4,5];
      print_r(array_merge_recursive_distinct($array1,$array2));
      $array1 = [1,2,3,6,12,19];
      $array2 = [1,2,3,4,5];
      print_r(array_merge_recursive_distinct($array1,$array2));
      // output
      Array
      (
          [0] => 1
          [1] => 2
          [2] => 3
          [3] => 4
          [4] => 5
      )
      Array
      (
          [0] => 1
          [1] => 2
          [2] => 3
          [3] => 4
          [4] => 5
          [5] => 6
          [6] => 12
          [7] => 19
      )
      

      PHP Sandbox上测试它

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-31
        • 1970-01-01
        • 1970-01-01
        • 2011-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多