Merge two array’s recursively without adding new keys

Asked

Viewed 69 times

0

someone has some hint to merge two array’s but the second must replace the values of the first recursively but only of the keys that exist in the first, that is, the extra values that exist in the second cannot be included in the first. array_merge_recursive and array_replace_recursive do not meet because they include the values of the second in the first. I’ve tried some things but so far without a solution in fact, below one of the ways I’ve tried but I haven’t managed yet to multidimensional.

<?php

function popule($default, $data) {
    foreach ($data as $key => $d) {
        if (is_array($d)) {
            $more_array = array_filter($d, 'is_array');
            if (count($more_array) > 0) {
                $d = popule($default, $d);
            }

            $keys_remove = array_diff_key($d, $default);

            $data[$key] = array_diff_key($d, $keys_remove);
        }
    }

    return $data;
}

$default = array(
    'product_id' => 0,
    'own_id' => 0,
    'name' => '',
    'variation' => array(
        'sku' => 1
    )
);

$data[] = array(
    'product_id' => rand(),
    'own_id' => rand(),
    'name' => 'teste',
    'key_extra' => '5a4sd5teste',
    'variation' => array(
        'sku' => 1
    )
);

print_r(popule($default, $data));

The result I would like, would follow the example below

<?php
$default = array(
    'product_id' => 0,
    'name' => '',
    'variation' => array(
        'sku' => 1
    )
);

$data[] = array(
    'product_id' => rand(),
    'name' => 'teste',
    'key_extra' => 4545,
    'variation' => array(
        'sku' => 10,
        'key1' => 4545,
        'key2' => 4545,
    )
);

// Resultado Esperado, foi mesclado $default em $data substuindo somente as chaves presentes em $default, as demais foram ignoradas
$data[] = array(
    'product_id' => 5465454,
    'name' => 'teste',
    'variation' => array(
        'sku' => 10
    )
);

It was solved with the solution presented below by Jrd, for my case which is a collection of data, was thus:

<?php 
$data[] = array();
$data[] = array();
// .
// .
// .
$data[] = array();

foreach ($data as $key => $_data) {
    $copy_default = $default;

    popule($copy_default, $_data);

    $data[$key] = $copy_default;
}
  • Your array model is exactly the one you put in the example or it should be dynamic to accept any array?

  • It should be dynamic to accept any array structure, with varying dimensions and depth.

1 answer

0

I imagine that function meets your needs

//&$default é o array a ser modificado, recebido como um parâmetro por referência e $data é o segundo array que irá sobrescrever o primeiro
function popule(&$default, $data){
    foreach($default as $key => &$item){ //percorremos todo o array usando sua posição como uma referência
        if(isset($data[$key])){ //verifica se a chave existe no segundo array
            if(is_array($item)){ //verifica se o índice em questão é um array
                popule($item, $data[$key]); //caso ele seja um array, envia para a mesma função para percorre-lo e procurar seus índices
            }else{
                $item = $data[$key]; //caso seja um valor, atribui o valor do segundo array ao primeiro
            }
        }
    }
}

The function traverses the entire first array and comparing whether the indices of the two are equal, accessing recursively if the index is an array or assigning the value of the second to the first if it is a value.

Link to the tests carried out

  • Thank you Jrd, solved perfectly for me.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.