Showing posts with label PHP Merge Arrays. Show all posts
Showing posts with label PHP Merge Arrays. Show all posts

Tuesday, 11 September 2018

Using + to merge arrays with PHP

I've been working at a new job and the interesting thing when working with other people's code is you often learn a heap of stuff you didn't already know. A couple of weeks ago I came across a way to merge arrays in PHP with the + operator, instead of using the array functions (e.g. array_merge) so share this here.

Example

The easiest way to illustrate this is with an example.
Using the plus operator to merge an array really works best with an associative array, otherwise it merges on the numbered indexes, which can lead to some unexpected or odd results.
Here's a couple of arrays, with some intersecting elements and some different elements.
$array1 = array(
    'fruit' => 'apple',
    'vegetable' => 'carrot',
    'drink' => 'water',
    'snack' => 'chips'
);
$array2 = array(
    'fruit' => 'banana',
    'drink' => 'juice',
    'sport' => 'running'
);
The order of precedence with using the + operator to merge these arrays is from left to right. So if we add $array1 and $array2 like so, 'apple' has precendence over 'banana' for the fruit element:
$array3 = $array1 + $array2;
Doing this:
print_r($array3);
results in this:
Array
(
    [fruit] => apple
    [vegetable] => carrot
    [drink] => water
    [snack] => chips
    [sport] => running
)
And the other way around:
$array3 = $array2 + $array1;
print_r($array3);
results in this:
Array
(
    [fruit] => banana
    [drink] => juice
    [sport] => running
    [vegetable] => carrot
    [snack] => chips
)

Related posts:

Thursday, 30 August 2018

PHP merges two arrays on the same key value AND


I have two arrays. And I want to merge them on the same key AND value. If they have the same ur_user_id then they are merged. array2 only provides some additional data for array1, so the new_array.length = array1.length. array1 just gets the additional data from array2.


$array1 =
    array(
        array('ur_user_id'=> 1,'ur_fname'=>'PerA','ur_lname'=>'SonA'),
        array('ur_user_id'=> 2,'ur_fname'=>'PerB','ur_lname'=>'SonB'),
        array('ur_user_id'=> 3,'ur_fname'=>'PerC','ur_lname'=>'SonC'),
    );
$array2 =
    array(
        array('ur_user_id' => 5,'ur_code' => 'EE','ur_user_role' => 'testE'),
        array('ur_user_id' => 4,'ur_code' => 'DD','ur_user_role' => 'testD'),
        array('ur_user_id' => 6,'ur_code' => 'FF','ur_user_role' => 'testF'),
        array('ur_user_id' => 3,'ur_code' => 'CC','ur_user_role' => 'testC'),
        array('ur_user_id' => 1,'ur_code' => 'AA','ur_user_role' => 'testA'),
        array('ur_user_id' => 2,'ur_code' => 'BB','ur_user_role' => 'testB'),
    );

Then the new array must look like this. It will have both the values from the array1and array2.
$new_array =
    array(
        array('ur_user_id'=> 1,'ur_fname'=>'PerA','ur_lname'=>'SonA','ur_code' => 'AA','ur_user_role' => 'testA'),
        array('ur_user_id'=> 2,'ur_fname'=>'PerB','ur_lname'=>'SonB','ur_code' => 'BB','ur_user_role' => 'testB'),
        array('ur_user_id'=> 3,'ur_fname'=>'PerC','ur_lname'=>'SonC','ur_code' => 'CC','ur_user_role' => 'testC'),
    );

The array1.length is always less than or equal to array2.length never greater. And the order of both arrays will not be always ordered. I've tried the function below which I got somewhere here but it doesn't work for me and I'm not really good with loops.
function merge_common_keys(){
    $arr = func_get_args();
    $num = func_num_args();

    $keys = array();
    $i = 0;
    for ($i=0; $i<$num; ++$i){
        $keys = array_merge($keys, array_keys($arr[$i]));
    }
    $keys = array_unique($keys);

    $merged = array();

    foreach ($keys as $key){
        $merged[$key] = array();
        for($i=0; $i<$num; ++$i){
            $merged[$key][] = isset($arr[$i][$key]) ? $arr[$i][$key] : null;
        }
    }
    return $merged;
}

Based on the given arrays the result is like this. It only merges on the same key.
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [ur_user_id] => 1
                    [ur_fname] => PerA
                    [ur_lname] => SonA
                )

            [1] => Array
                (
                    [ur_user_id] => 5
                    [ur_code] => AA-BB-CC
                    [ur_user_role] => testE
                )

        )


Try out this code, It might help you, it's short and without traversing loops:
    usort($array2,function($a,$b){
        return strnatcmp($a['ur_user_id'],$b['ur_user_id']);
    });
    $array3 = array_replace_recursive($array1, $array2);

    $result = array_uintersect($array3,$array1,function($a,$b){
        return strnatcmp($a['ur_user_id'],$b['ur_user_id']);
    });
    print_r($result);

Output
Array
(
    [0] => Array
        (
            [ur_user_id] => 1
            [ur_fname] => PerA
            [ur_lname] => SonA
            [ur_code] => AA
            [ur_user_role] => testA
        )

    [1] => Array
        (
            [ur_user_id] => 2
            [ur_fname] => PerB
            [ur_lname] => SonB
            [ur_code] => BB
            [ur_user_role] => testB
        )

    [2] => Array
        (
            [ur_user_id] => 3
            [ur_fname] => PerC
            [ur_lname] => SonC
            [ur_code] => CC
            [ur_user_role] => testC
        )

)