PHP深度扩展阵列

时间:2012-10-04 10:17:48

标签: php jquery json array-merge

如何对多维关联数组进行深度扩展(用于解码的JSON对象)。 我需要PHP等价的jQuery's $.extend(true, array1, array2)与数组而不是JSON和PHP。

这是我需要的一个例子(array_merge_recursive似乎没有做同样的事情)

$array1 = ('1'=> ('a'=>'array1a', 'b'=>'array1b'));
$array2 = ('1'=> ('a'=>'array2a', 'c'=>'array2b'));

$array3 = array_extend($array1, $array2);

//$array3 = ('1'=> ('a'=>'array2a', 'b'=>'array1b', 'c'=>'array2b'))

注意如果array1具有相同的值(如类的扩展如何工作),array2将如何覆盖array1

7 个答案:

答案 0 :(得分:23)

如果您使用的是PHP 5.3.0+,则可以使用array_replace_recursive来完全满足您的需求:

  

array_replace_recursive()用相同的值替换array1的值   来自以下所有数组的值。如果是第一个数组的一个键   存在于第二个数组中,其值将被该值替换   从第二个数组。如果密钥存在于第二个数组中,则不存在   第一个,它将在第一个数组中创建。如果只存在密钥   在第一个数组中,它将保持原样。如果是几个阵列   通过更换,他们将按顺序处理,后来   数组覆盖以前的值。

答案 1 :(得分:2)

我使用的方法与使用angular.extend(dst,src)和jQuery.extend()的方式相同。

function extend($base = array(), $replacements = array()) {
    $base = ! is_array($base) ? array() : $base;
    $replacements = ! is_array($replacements) ? array() : $replacements;

    return array_replace_recursive($base, $replacements);
}

示例:

si()是一个实用程序清理函数,它可以获取$ _POST或$ _GET并返回一个数组。

        $s = extend(array(
            'page' => 1,
            'take' => 100,
            'completed' => 1,
            'incomplete' => 1,
        ), si());

答案 2 :(得分:1)

取自array_merge docs:

function array_extend($a, $b) {
    foreach($b as $k=>$v) {
        if( is_array($v) ) {
            if( !isset($a[$k]) ) {
                $a[$k] = $v;
            } else {
                $a[$k] = array_extend($a[$k], $v);
            }
        } else {
            $a[$k] = $v;
        }
    }
    return $a;
}

答案 3 :(得分:1)

这可能就是你要找的东西:

function array_extend(&$result) {
  if (!is_array($result)) {
    $result = array();
  }

  $args = func_get_args();

  for ($i = 1; $i < count($args); $i++) {
    // we only work on array parameters:
    if (!is_array($args[$i])) continue;

    // extend current result:
    foreach ($args[$i] as $k => $v) {
      if (!isset($result[$k])) {
        $result[$k] = $v;
      }
      else {
        if (is_array($result[$k]) && is_array($v)) {
          array_extend($result[$k], $v);
        }
        else {
          $result[$k] = $v;
        }
      }
    }
  }

  return $result;
}

用法:

$arr1 = array('a' => 1, 'b' => 2, 'c' => 3);
$arr2 = array('b' => 'b', 'd' => 'd');
array_extend($arr1, $arr2);
print_r($arr1); // array('a' => 1, 'b' => 'b', 'c' => 3, 'd' => 'd')

// or, to create a new array and leave $arr1 unchanged use:
array_extend($arr3, $arr1, $arr2);
print_r($arr3); // array('a' => 1, 'b' => 'b', 'c' => 3, 'd' => 'd')

// or, use the return value:
print_r(array_extend($arr1, $arr2)); // but this will also modify $arr1

答案 4 :(得分:1)

您应该使用:https://github.com/appcia/webwork/blob/master/lib/Appcia/Webwork/Storage/Config.php#L64

/**
 * Merge two arrays recursive
 *
 * Overwrite values with associative keys
 * Append values with integer keys
 *
 * @param array $arr1 First array
 * @param array $arr2 Second array
 *
 * @return array
 */
public static function merge(array $arr1, array $arr2)
{
    if (empty($arr1)) {
        return $arr2;
    } else if (empty($arr2)) {
        return $arr1;
    }

    foreach ($arr2 as $key => $value) {
        if (is_int($key)) {
            $arr1[] = $value;
        } elseif (is_array($arr2[$key])) {
            if (!isset($arr1[$key])) {
                $arr1[$key] = array();
            }

            if (is_int($key)) {
                $arr1[] = static::merge($arr1[$key], $value);
            } else {
                $arr1[$key] = static::merge($arr1[$key], $value);
            }
        } else {
            $arr1[$key] = $value;
        }
    }

    return $arr1;
}

答案 5 :(得分:0)

通过一点谷歌搜索,我发现了这个:

/**
 * jquery style extend, merges arrays (without errors if the passed values are not arrays)
 *
 * @return array $extended
 **/
function extend() {
    $args = func_get_args();
    $extended = array();
    if(is_array($args) && count($args)) {
        foreach($args as $array) {
            if(is_array($array)) {
                $extended = array_merge($extended, $array);
            }
        }
    }
    return $extended;
}

extend($defaults, $new_options);

答案 6 :(得分:0)

我想这是正确答案,因为:

  • 你的回答有一个警告错误:

    警告:不能在...中使用标量值作为数组

因为$ a并不总是数组而你使用$ a [$ k]。

  • array_merge_recursive确实合并了数组,但它将带有重复键的值转换为数组,而不是像第一个数组一样用第二个数组中的重复值覆盖第一个数组中的值,如array_merge那样。

  • 其他aswers不是递归或不简单。

所以,这是我的答案:没有错误的答案:

function array_extend(array $a, array $b) {
    foreach($b as $k=>$v) {
        if( is_array($v) ) {
            if( !isset($a[$k]) ) {
                $a[$k] = $v;
            } else {
                if( !is_array($a[$k]){
                    $a[$k]=array();
                }
                $a[$k] = array_extend($a[$k], $v);
            }
        } else {
            $a[$k] = $v;
        }
    }
    return $a;
}

我的回答是三元运算符:

function array_extend(array $a, array $b){
    foreach($b as $k=>$v)
            $a[$k] = is_array($v)&&isset($a[$k])?
                array_extend(is_array($a[$k])?
                        $a[$k]:array(),$v):
                $v;
    return $a;
}

编辑:还有一个你想要的阵列奖金:

function array_extend(){
    $args = func_get_args();
    while($extended = array_shift($args))
            if(is_array($extended))
                    break;
    if(!is_array($extended))
            return FALSE;
    while($array = array_shift($args)){
        if(is_array($array))
                foreach($array as $k=>$v)
                        $extended[$k] = is_array($v)&&isset($extended[$k])?
                            array_extend(is_array($extended[$k])?
                                    $extended[$k]:array(),$v):
                            $v;
    }
    return $extended;
}