8

I am trying to merge the following two arrays into one array, sharing the same key:

$array1 = [
    ["Camera1" => "192.168.101.71"],
    ["Camera2" => "192.168.101.72"],
    ["Camera3" => "192.168.101.74"],
];

$array2 = [
    ["Camera1" => "VT"],
    ["Camera2" => "UB"],
    ["Camera3" => "FX"]
];

As you can see, they share the same key (Camera1, Camera2, Camera3, etc..)

Here is what I have tried:

$Testvar = array_merge($NewArrayCam, $IpAddressArray);
foreach ($Testvar as $Newvals) {
    $cam = array();
    foreach ($Newvals as $K => $V) {
        $cam[] = array($K => $V);
    }
}

My desired result:

[
    'Camera1' => [
        'ip' => '192.168.101.71',
        'name' => 'VT',
    ],
    'Camera2' => [
        'ip' => '192.168.101.72',
        'name' => 'UB',
    ],
    'Camera3' => [
        'ip' => '192.168.101.74',
        'name' => 'FX',
    ]
]
4
  • 5
    Can you provide the desired output please ? Commented Feb 12, 2013 at 21:36
  • desire output array() camera1 array ip => xx.xx.xx.xx, name => VT, etc Commented Feb 12, 2013 at 21:41
  • Are you getting these arrays from a database? If so then maybe there is a better way to merge them (i.e. doing it using the database's query language). Merging it like this, after the fact, is a little tedious. Commented Feb 12, 2013 at 22:07
  • array_replace_recursive Commented Oct 20, 2017 at 13:52

11 Answers 11

11

Ideally I would look to format the two arrays in such a way that array_merge_recursive would simply merge the arrays without too much fuss.

However I did come up with a solution that used array_map.

$array1 = array(
    array("Camera1" => "192.168.101.71"),
    array("Camera2" => "192.168.101.72"),
    array("Camera3" => "192.168.101.74"),
);

$array2 = array(
    array("Camera1" => "VT"),
    array("Camera2" => "UB"),
    array("Camera3" => "FX")
);

$results = array();

array_map(function($a, $b) use (&$results) {

    $key = current(array_keys($a));
    $a[$key] = array('ip' => $a[$key]);

    // Obtain the key again as the second array may have a different key.
    $key = current(array_keys($b));
    $b[$key] = array('name' => $b[$key]);

    $results += array_merge_recursive($a, $b);

}, $array1, $array2);

var_dump($results);

The output is:

array (size=3)
  'Camera1' => 
    array (size=2)
      'ip' => string '192.168.101.71' (length=14)
      'name' => string 'VT' (length=2)
  'Camera2' => 
    array (size=2)
      'ip' => string '192.168.101.72' (length=14)
      'name' => string 'UB' (length=2)
  'Camera3' => 
    array (size=2)
      'ip' => string '192.168.101.74' (length=14)
      'name' => string 'FX' (length=2)
Sign up to request clarification or add additional context in comments.

2 Comments

Throws an Error: Unsupported operand types (+=)
I just tested the code above on PHP 5.5.14 and it works fine. Check what the output of array_merge_recursive is, it may not be an array.
8

Try to use array_merge_recursive.

3 Comments

Just beat me to the punch.
The problem of array_merge_recursive() is that it works only with non-numeric keys, so at first you have to convert it into associative array.
I agree, array_merge_recursive() will definitely not work for this data.
8

Use array_merge_recursive :

Convert all numeric key to strings, (make is associative array)

$result = array_merge_recursive($ar1, $ar2);
print_r($result);

Ref : http://php.net/array_merge_recursive

Comments

8

For your nesting level will be enough this:

$sumArray = array_map(function ($a1, $b1) { return $a1 + $b1; }, $array1, $array2);

For deeper nesting it wont work.

Comments

2

If both arrays have the same numbers of levels and keys this should work:

$array3 = array();

foreach ($array1 as $key1 => $value1) {
  // store IP
  $array3['Camera'.$key1]['IP'] = $value['Camera'.$key1]; 
  // store type of cam
  $array3['Camera'.$key1]['Type'] = $array2[$key]['Camera'.$key1]; 

}

At the end $array3 should be something like:

$array3 = array {

["Camera1"] => {['IP'] => "192.168.101.71", ['Type'] => "VT" }
["Camera2"] => {['IP'] => "192.168.101.72", ['Type'] => "UB" }
["Camera3"] => {['IP'] => "192.168.101.74", ['Type'] => "FX" }

}

Comments

2
this would be one of the soluion:

function array_merge_custom($array1,$array2) {
    $mergeArray = [];
    $array1Keys = array_keys($array1);
    $array2Keys = array_keys($array2);
    $keys = array_merge($array1Keys,$array2Keys);

    foreach($keys as $key) {
        $mergeArray[$key] = array_merge_recursive(isset($array1[$key])?$array1[$key]:[],isset($array2[$key])?$array2[$key]:[]);
    }

    return $mergeArray;

}

$array1 = array(
    array("Camera1" => "192.168.101.71"),
    array("Camera2" => "192.168.101.72"),
    array("Camera3" => "192.168.101.74"),
);

$array2 = array(
    array("Camera1" => "VT"),
    array("Camera2" => "UB"),
    array("Camera3" => "FX")
);
echo '<pre>';
print_r(array_merge_custom($array1 , $array2));

Comments

0

The main problem are the arrays. Because of the way they are structured it becomes unnecessarily complicated to merge them. It they simply were normal associative arrays (i.e. array('Camera1' => 'VT') then it would be effortless to merge them.

I would suggest that you figure out how to format the data in such a way as to make it easier to work with.

This is a quick and dirty way of merging the two arrays. It takes one "camera" from one array, and then tries to find the corresponding "camera" in the other array. The function only uses the "cameras" in the $ips array, and only uses matching CameraN keys.

$ips = array(
    array('Camera1' => '192.168.101.71'),
    array('Camera2' => '192.168.101.72'),
    array('Camera3' => '192.168.101.74'),
);
$names = array(
    array('Camera1' => 'VT'),
    array('Camera2' => 'UB'),
    array('Camera3' => 'FX'),
);
function combineCameras($ips, $names) {
    $output = array();
    while ($ip = array_shift($ips)) {
        $ident = key($ip);
        foreach ($names as $key => $name) {
            if (key($name) === $ident) {
                $output[$ident] = array(
                    'name' => array_shift($name),
                    'ip' => array_shift($ip),
                );
                unset($names[$key]);
            }
        }
    }
    return $output;
}
var_dump(combineCameras($ips, $names));

Comments

0

Something like this should work:

$array1 = array(array("Camera1" => "192.168.101.71"), array("Camera2" => "192.168.101.72"), array("Camera3" => "192.168.101.74"));
$array2 = array(array("Camera1" => "VT"), array("Camera2" => "UB"), array("Camera3" => "FX"));
$results = array();

foreach($array1 as $key => $array){
  foreach($array as $camera => $value){
    $results[$camera]['ip'] = $value;
  }
}

foreach($array2 as $key => $array){
  foreach($array as $camera => $value){
    $results[$camera]['name'] = $value;
  }
}
print_r($results);

Comments

0

This worked for me. I joined two arrays with the same keys

$array1 = ArrayUtils::merge($array1, $array2);

If you need preserve NumericKey, use

$array1 = ArrayUtils::merge($array1, $array2, true);

1 Comment

Please keep in mind that this will only work if you use Zend Framework.
0

You could convert all numeric keys to strings and use array_replace_recursive which:

merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns the resulting array.

Example

$arr1 = [
    'rate' => 100   
];

$arr2 = [
    'rate' => 100,
    'name' => 'Best Name In Town',
];

print_r(array_replace_recursive($arr1, $arr2));

Output

Array
(
    [rate] => 100
    [name] => Best Name In Town
)

1 Comment

This implemented advice does not resemble the sample data structures in the asked question.
0

Spreading the two arrays inside of an array_merge_recursive() is an attractive tool, but there is no callback parameter to create the desired subarray keys. The input arrays need to be re-keyed/restructured in advance. With associative, non-numeric keys on all levels, subsequently merged arrays will be grouped appropriately regardless of their order. Demo

array_walk_recursive($array1, fn(&$v) => $v = ['ip' => $v]);

array_walk_recursive($array2, fn(&$v) => $v = ['name' => $v]);

var_export(
    array_merge_recursive(...$array1, ...$array2)
);

Or a fully nested approach:

var_export(
    array_merge_recursive(
        ...array_map(
            fn($sub) => [key($sub) => ['ip' => current($sub)]],
            $array1
        ),
        ...array_map(
            fn($sub) => [key($sub) => ['name' => current($sub)]],
            $array2
        )
    )
);

Output (from either):

array (
  'Camera1' => 
  array (
    'ip' => '192.168.101.71',
    'name' => 'VT',
  ),
  'Camera2' => 
  array (
    'ip' => '192.168.101.72',
    'name' => 'UB',
  ),
  'Camera3' => 
  array (
    'ip' => '192.168.101.74',
    'name' => 'FX',
  ),
)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.