21

多次元連想配列を深く拡張するにはどうすればよいですか(デコードされたJSONオブジェクトで使用するため)。JSONの代わりに配列を使用したjQuery$.extend(true, array1, array2)と同等のphpと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_recursiveを正確に実行するものを使用できます。

array_replace_recursive()は、array1の値を、後続のすべての配列の同じ値に置き換えます。最初の配列のキーが2番目の配列に存在する場合、その値は2番目の配列の値に置き換えられます。キーが最初の配列ではなく2番目の配列に存在する場合、そのキーは最初の配列に作成されます。キーが最初の配列にのみ存在する場合、そのキーはそのままになります。複数の配列が置換のために渡された場合、それらは順番に処理され、後の配列が前の値を上書きします。

于 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

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 に答える
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 に答える
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 に答える
0

私はここに正しい答えがあると思います、なぜなら:

  • あなたの答えには警告付きのバグがあります:

    警告:スカラー値を配列として使用することはできません...

$ aは常に配列であるとは限らず、$ a[$k]を使用するためです。

  • array_merge_recursiveは実際に配列をマージしますが、array_mergeのように最初の配列の値を2番目の配列の重複値で上書きするのではなく、重複キーを持つ値を配列に変換します。

  • 他のアワーは再帰的でも単純でもありません。

だから、ここに私の答えがあります:バグのないあなたの答え:

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

編集:そして、必要な数のアレイを備えたボーナス1:

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 に答える