array_replace_recursive перезаписывают ключи вместо добавляемых ключей - PullRequest
1 голос
/ 19 марта 2020

Я пытаюсь наложить или заменить массив другим массивом, если хотите. Для этого я пытался использовать функцию array_replace_recursive, но я получаю нежелательное поведение, которое, похоже, не могу устранить.

У меня есть два массива:

Исходный массив:

[test] => Array
            [me] => Array
                    [0] => test
                    [1] => me
                    [2] => now
            [me2] => Array
                    [0] => test
                    [1] => me
                    [2] => now

И массив, который я хочу заменить

[test] => Array
            [me2] => Array
                    [name] => firstname
                    [last] => lastname

После использования array_replace_recursive ( $ first_array, $ second_array) я получаю следующий вывод:

 [test] => Array
            [me] => Array
                    [0] => test
                    [1] => me
                    [2] => now
            [me2] => Array
                    [0] => test <-- this needs to be overwritten not appended
                    [1] => me <-- this needs to be overwritten not appended
                    [2] => now <-- this needs to be overwritten not appended
                    [name] => firstname
                    [last] => lastname

Мне действительно нужно, чтобы значение ['test'] ['me2'] было перезаписано и не добавлено. Таким образом, ключи 0,1,2 должны быть пропущены. Может ли кто-нибудь указать мне правильное направление здесь?

Ответы [ 2 ]

1 голос
/ 20 марта 2020

Рид,

Спасибо, это сработало для меня ... но я вдохновился вашим кодом и начал улучшать его. Для других людей, которым нужно что-то вроде этого:

    function conf_get($paths, $array) {
        $paths = !is_array($paths) ? [] : $paths;
        foreach ($paths as $path)
            $array = $array[$path];
        return $array;
    }
    function conf_set($paths, $value, $array) {
        $array = !is_array($array) ? [] : $paths; // Initialize array if $array not set
        $result = &$array;
        foreach ($paths as $i => $path) {
            if ($i < count($paths) - 1) {
                if (!isset($result[$path]))
                    $result[$path] = [];
                $result = &$result[$path];
            } else
                $result[$path] = $value;
        }
        return $result;
    }

    $config = [];
    $config ['test']['me'] = ['test', 'me', 'now'];
    $config ['test']['me2'] = ['test', 'me', 'now'];

echo "\n INITIAL CONFIG"; 
print_r($config );
echo "\n GET PATH test"; 
print_r(conf_get('test', $config));
echo "\n GET PATH test,me1" ;
print_r(conf_get(['test', 'me2'], $config);
echo "\n REPLACE PATH test,me2 with new array" ;
print_r(conf_set(['test', 'me2'], ['name' => 'firstname', 'last' => 'lastname'], $config), "");
echo "\n ADD PATH test,me6 with new array";
print_r(conf_set(['test', 'me6'], ['name' => 'firstname', 'last' => 'lastname'], $config));

Результат:


[INITIAL CONFIG]
    [test] => Array
            [me] => Array
                    [0] => test
                    [1] => me
                    [2] => now
            [me2] => Array
                    [0] => test
                    [1] => me
                    [2] => now

[GET PATH test]
    [test] => Array
            [me] => Array
                    [0] => test
                    [1] => me
                    [2] => now
            [me2] => Array
                    [0] => test
                    [1] => me
                    [2] => now

[GET PATH test,me1]
    [0] => test
    [1] => me
    [2] => now

[REPLACE PATH test,me2 with new array]
    [me2] => Array
            [name] => firstname
            [last] => lastname

[ADD PATH test,me6 with new array]
    [me6] => Array
            [name] => firstname
            [last] => lastname
1 голос
/ 20 марта 2020

Вы, вероятно, должны написать свою собственную функцию, которая выполняет замену так, как вам удобно Я думаю, что это должно:

  • принять два массива ($ a, $ b) в качестве параметров
  • , если $ a [KEY] является массивом, а $ b [KEY] не является установите, сохраняйте $ a [KEY]
  • , если $ a [KEY] - массив, а $ b [KEY] - массив, вызывайте этот метод w / ($ a [KEY] & $ b [KEY] )
  • если дети $ a НЕ являются массивами, а у $ b есть дети, замените $ a на $ b

или что-то в этом роде ... Мне было трудно понять, что именно вам нужно было, и при написании функции для нее были крайние случаи, которые, как я понял, могли возникнуть в более сложных массивах.

Итак, я написал эту функцию и тест. Я проверил его только с примерами массивов, которые вы дали, но он дает правильный вывод для них. Это может привести к ошибкам, если вы добавите другой слой в массив или если там есть массив, в котором есть несколько дочерних элементов, которые являются массивами, и некоторые дочерние элементы, которые не являются массивами.

<?php

function recurseReplace($a,$b){
    $ret = [];
    foreach ($a as $key=>$value){
        if (!isset($b[$key])&&is_array($value)){
            $ret[$key] = $value;
            continue;
        } 
        if (is_array($value)&&isset($b[$key])&&is_array($b[$key])){
            $ret[$key] = recurseReplace($value,$b[$key]);
            continue;
        }
    }
    if (count($ret)==0){
        foreach ($b as $key=>$value){
            $ret[$key] = $value;
        }
    }
    return $ret;
}

$a = [
    "test" => [
        "me"=>['test','me','now'],
        "me2"=>["test",'me','now']
        ]
    ];

$b = [
    "test" => [
        "me2"=>["name"=>'firstname',"last"=>"lastname"]
        ]
    ];

$desired = [
    "test" => [
        "me"=>['test','me','now'],
        "me2"=>["name"=>'firstname',"last"=>"lastname"]
        ]
    ];

$final = recurseReplace($a,$b);
echo "\n\n-----final output::---\n\n";

print_r($final);
echo "\n\n-----desired::---\n\n";

print_r($desired);
...