【问题标题】:php recursive mergephp递归合并
【发布时间】:2011-10-21 23:39:15
【问题描述】:

我需要以某种不同的方式合并一些数组,我使用 array_merge_recursive。 但是有一些东西我需要改变,我不知道如何改变。 这是来自 php.net 的引用

但是,如果数组具有相同的数字键,则后面的值 不会覆盖原始值,但会被追加。

我想要这个值,而不是被附加,我不想在新数组中附加确切的值。希望你理解这一点。

例子:

$array = array(
   'some'  => array(
       'other'    => 'key',
   ),
);

$array2 = array();
$array2['some']['other'] = 'key2';

如果我使用 array_merge_recursive 会产生这样的结果:

Array (
    [some] => Array
        (
            [other] => Array
                (
                    [0] => key
                    [1] => key2
                )
        ) )

我希望它匹配相同的结果,而不是追加它。是的,我知道,你会说,然后使用 array_merge,但它也不能很好地工作。 如果我使用这个:

$array = array(
   'some'  => array(
       'other'    => 'key',
   ),
);

$array2 = array();
$array2['some']['other2'] = 'key2';

print_r(array_merge($array, $array2));

它会从列表中删除$array[some][other],只留下$array[some][other2]。我不知道哪个更好,因为没有人让它变得更好。

【问题讨论】:

  • 你的数组中的嵌套有多深?只有一层?
  • 那么告诉我们你的结果应该是什么?
  • 嗯,它可能是无限的。我不会只使用它的1级。
  • @scube 结果应该是(如果使用 array_merge)不要从第一个数组中删除先前的项目。第二个示例显示: Array ( [some] => Array ( [other2] => key2 ) ) 我想显示: Array ( [some] => Array ( [other] => key [other2] => key2 ) )
  • @Alex: 你对执行这个有什么期望: $array = array( 'some' => array( 'other' => 'key', ), ); $array2['some']['other'] = 'key2';何时使用 array_merge_recursive?

标签: php arrays recursion merge


【解决方案1】:

对于 PHP >= 5.3,只需使用 array_replace_recursive

【讨论】:

    【解决方案2】:

    试试这个

    <?php
    function mymerge(&$a,$b){ //$a will be result. $a will be edited. It's to avoid a lot of copying in recursion
        foreach($b as $child=>$value){
            if(isset($a[$child])){ 
                if(is_array($a[$child]) && is_array($value)){ //merge if they are both arrays
                    mymerge($a[$child],$value);
                }
                //else ignore, you can add your own logic, i.e when 1 of them is array
            }
            else
                $a[$child]=$value; //add if not exists
        }
    
        //return $a;
    }
    

    【讨论】:

    • 这个答案可能不正确。因为我测试了你的答案,结果与我预期的不一样。你能看看这个链接吗? link
    【解决方案3】:

    另一种选择,来自 drupal 的 array_merge_deep

    function array_merge_deep($arrays) {
      $result = array();
      foreach ($arrays as $array) {
        foreach ($array as $key => $value) {
          // Renumber integer keys as array_merge_recursive() does. Note that PHP
          // automatically converts array keys that are integer strings (e.g., '1')
          // to integers.
          if (is_integer($key)) {
            $result[] = $value;
          }
          // Recurse when both values are arrays.
          elseif (isset($result[$key]) && is_array($result[$key]) && is_array($value)) {
            $result[$key] = array_merge_deep(array($result[$key], $value));
          }
          // Otherwise, use the latter value, overriding any previous value.
          else {
            $result[$key] = $value;
          }
        }
      }
      return $result;
    }
    

    【讨论】:

      【解决方案4】:

      我为它写了我的合并类:

      <?php
      
      class ArrayMerge
      {
      
          /**
           * @param array $a
           * @param array $b
           *
           * @return array
           */
          public function merge ( $a, $b ) {
              foreach ( $b as $k => $v ) {
                  if ( is_array( $v ) ) {
                      if ( isset( $a[ $k ] ) ) {
                          if ( $this->isDeep( $v ) ) {
                              $a[ $k ] = $this->merge( $a[ $k ], $v );
                          } else {
                              $a[ $k ] = array_merge( $a[ $k ], $v );
                          }
                      } else {
                          $a[ $k ] = $v;
                      }
                  } else {
                      $a[ $k ] = $v;
                  }
              }
              return $a;
          }
      
          /**
           * @param array $array
           *
           * @return bool
           */
          private function isDeep ( $array ) {
              foreach ( $array as $elm ) {
                  if ( is_array( $elm ) ) {
                      return TRUE;
                  }
              }
              return FALSE;
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        我从 RiaD 的版本开始并添加了对象处理。需要测试和反馈

        function recursiveMerge(&$a,$b){ //$a will be result. $a will be edited. It's to avoid a lot of copying in recursion
                if(is_array($b) || is_object($b)){
                    foreach($b as $child=>$value){
                        if(is_array($a)){
                            if(isset($a[$child]))
                                recursiveMerge($a[$child],$value);
                            else
                                $a[$child]=$value;
                        }
                        elseif(is_object($a)){
                            if(isset($a->{$child}))
                                recursiveMerge($a->{$child},$value);
                            else
                                $a->{$child}=$value;
                        }
                    }
                }
                else
                    $a=$b;
            }
        

        【讨论】:

          猜你喜欢
          • 2017-07-19
          • 1970-01-01
          • 2014-10-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-07
          • 1970-01-01
          • 2021-11-06
          相关资源
          最近更新 更多