21

如何对多维关联数组进行深度扩展(用于解码的 JSON 对象)。我需要使用数组而不是 JSON 和 PHP的jQuery 的$.extend(true, array1, array2)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'))

请注意如果 array2 具有相同的值,它是如何覆盖 array1 的(例如类扩展的工作方式)

4

7 回答 7

24

如果你有 PHP 5.3.0+,你可以使用array_replace_recursivewhich 完全符合你的需要:

array_replace_recursive()将 array1 的值替换为以下所有数组中的相同值。如果第一个数组中的键存在于第二个数组中,则其值将被第二个数组中的值替换。如果键存在于第二个数组中,而不是第一个数组中,它将在第一个数组中创建。如果一个键只存在于第一个数组中,它将保持原样。如果传递了多个数组进行替换,它们将按顺序处理,后面的数组会覆盖前面的值。

于 2013-10-24T01:40:43.480 回答
2

这可能是您正在寻找的:

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
于 2013-04-02T08:55:34.623 回答
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());
于 2013-08-04T16:42:21.180 回答
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;
}
于 2014-02-27T10:29:36.100 回答
1

取自array_merge文档:

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;
}
于 2012-10-04T10:17:48.383 回答
0

I guess here is the correct answer, because:

  • your answer have a bug with warning:

    Warning: Cannot use a scalar value as an array in...

Because $a is not always an array and you use $a[$k].

  • array_merge_recursive does indeed merge arrays, but it converts values with duplicate keys to arrays rather than overwriting the value in the first array with the duplicate value in the second array, as array_merge does.

  • other aswers are not recursives or not simple.

So, here is my answer: your answer without bugs:

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;
}

And my answer with ternary operator:

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;
}

Edit: And a bonus one with as many arrays you want:

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;
}
于 2013-06-19T10:10:22.203 回答
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);
于 2013-02-06T16:17:33.997 回答