SAHAR SAHAR - 5 months ago 19
PHP Question

How to combine two arrays by deep key?

I want to combine two arrays using specified deep subarray values.

I have two different arrays with different structures and I want to combine them so that if the "primary keys" match then add second array's values to the first array, if not then create array with array 2's value.

Primary key in first array is

[created_by]
and in second array it's
[upgrade_by]


Array1 is:

Array(
[0] => Array(
[Customer] => Array(
[created_by] => 5
[amount] => 199
[name] => First Cux
)
)
[1] => Array(
[Customer] => Array(
[created_by] => 1
[amount] => 199
[name] => Last Cux
)
)
)


Array 2 is

Array(
[0] => Array(
[0] => Array(
[refund_amount] => 100
)
[Historycustomer] => Array(
[upgrade_by] => 1
[company] => First Company
)
)
[1] => Array(
[0] => Array(
[refund_amount] => 250
)
[Historycustomer] => Array(
[upgrade_by] => 3
[company] => Last Company
)
)
)


I need result like this:

Array(
[0] => Array(
[Customer] => Array(
[created_by] => 5
[amount] => 199
[name] => First Cux
)
)
[1] => Array(
[Customer] => Array(
[created_by] => 1
[amount] => 199
[refund_mount]=>100
[name] => Last Cux
[company] => First Company
)
)
[2] => Array(
[Customer] => Array(
[created_by] => 3
[refund_mount]=>250
[company] => Last Company
)
)
)


Primary key in first array is
[created_by]
and in second array it's
[upgrade_by]

Answer Source

My approach will use input array $a as the result array. foreach() will loop through the subarrays of $b. $index (the key of the subarray in $a which holds the upgrade_by value in its created_by value) is found by:

  1. Isolating the deepest subarrays in $a's Customer "columns" using array_column() -- these are the 3-element arrays.
  2. array_column() is used again to isolate the created_by values within these subarrays.
  3. array_search() hunts for the specified number in the new isolated array and if it exists, returns its index.

When the index is found, $b's values are merged with $a's values using the given index and the upgrade_by element is omitted.

When the index is not found, upgrade_by is renamed created_by and the elements are added to $a as a new customer subarray.

Code: (Demo Link)

$a=[
    ['Customer'=>['created_by'=>5,'amount'=>199,'name'=>'First Cux']],
    ['Customer'=>['created_by'=>1,'amount'=>199,'name'=>'Last Cux']]
];
$b=[
    [['refund_amount'=>100],'Historycustomer'=>['upgrade_by'=>1,'company'=>'First Company']],
    [['refund_amount'=>250],'Historycustomer'=>['upgrade_by'=>3,'company'=>'Last Company']]
];

foreach($b as $b1){
    $index=array_search($b1['Historycustomer']['upgrade_by'],array_column(array_column($a,'Customer'),'created_by'));
    if($index!==false){
        $a[$index]['Customer']+=['refund_amount'=>$b1[0]['refund_amount'],'company'=>$b1['Historycustomer']['company']];
    }else{
        $a[]=['Customer'=>['created_by'=>$b1['Historycustomer']['upgrade_by'],'refund_amount'=>$b1[0]['refund_amount'],'company'=>$b1['Historycustomer']['company']]];
    }
}
var_export($a);

Output:

array (
  0 => 
  array (
    'Customer' => 
    array (
      'created_by' => 5,
      'amount' => 199,
      'name' => 'First Cux',
    ),
  ),
  1 => 
  array (
    'Customer' => 
    array (
      'created_by' => 1,
      'amount' => 199,
      'name' => 'Last Cux',
      'refund_amount' => 100,
      'company' => 'First Company',
    ),
  ),
  2 => 
  array (
    'Customer' => 
    array (
      'created_by' => 3,
      'refund_amount' => 250,
      'company' => 'Last Company',
    ),
  ),
)