confused_geek
confused_geek

Reputation: 259

Combine two array using a field in PHP

I have an array in which i want to combine the common fields together. So that the common names get grouped together and they contain the common values of that particular name. Below is my array

[
  [
    count_employee: 2,
    name: "Harry"
  ],
  [
    count_employee: 61,
    name: "Jack"
  ],
  [
    count_employee: 11,
    name: "John"
  ],
  [
    count_warehouse: 1,
    name: "Harry"
  ],
  [
    count_warehouse: 77,
    name: "John"
  ],
  [
    count_warehouse: 45,
    name: "Jack"
  ]
]

I want the output to be

[
  [
    name: "Harry",
    count_employee:2
    count_warehouse:1
  ],
  [
    name: "Jack",
    count_employee: 61
    count_warehouse: 45
  ],
  [
    name: "John",
    count_employee:11
    count_warehouse:77
  ],
]

So far i have tried this out

foreach ($data as $key => $value) {
      $group[$value['name']]['name'] = $value['name'];
      $group[$value['name']][$key]['count_employee'] = $value['count_employee'];
      $group[$value['name']][$key]['count_warehouse'] = $value['count_warehouse'];
}

Upvotes: 1

Views: 791

Answers (3)

Progrock
Progrock

Reputation: 7485

Assuming all the array has a name key for each sub array contained within, we can use the name as a key for an array and merge arrays with corresponding name values.

<?php
$data=
[
  [
    'count_employee'=> 2,
    'name'=> 'Harry'
  ],
  [
    'count_employee'=> 61,
    'name'=> 'Jack'
  ],
  [
    'count_employee'=> 11,
    'name'=> 'John'
  ],
  [
    'count_warehouse'=> 1,
    'name'=> 'Harry'
  ],
  [
    'count_warehouse'=> 77,
    'name'=> 'John'
  ],
  [
    'count_warehouse'=> 45,
    'name'=> 'Jack'
  ]
];

$output = [];
foreach($data as $item) {
    $output[$item['name']] = array_merge($item, $output[$item['name']] ?? []);
}


var_export($output);

Output:

array (
    'Harry' => 
    array (
      'count_warehouse' => 1,
      'name' => 'Harry',
      'count_employee' => 2,
    ),
    'Jack' => 
    array (
      'count_warehouse' => 45,
      'name' => 'Jack',
      'count_employee' => 61,
    ),
    'John' => 
    array (
      'count_warehouse' => 77,
      'name' => 'John',
      'count_employee' => 11,
    ),
  )

Upvotes: 0

Rakesh Jakhar
Rakesh Jakhar

Reputation: 6388

You can use array_walk with array_key_exists

$res=[];
array_walk($arr, function($v,$k) use (&$res){
 if(array_key_exists($v['name'], $res))
  $res[$v['name']]['count_warehouse'] = $v['count_warehouse'];
 else
  $res[$v['name']] = $v;
});
print_r(array_values($res));

Live Demo

Upvotes: 0

Qirel
Qirel

Reputation: 26460

Loop over the array, and use the name as the index of each element. If no element by that index does not exist, define it as an empty array.

Then all you need to do is add the fields (if they exist) to the proper column.

Your issue was that you were creating an array with one too many dimensions, instead of adding each value to the current count - in addition to the fact that you will not always have both the warehouse and employee count defined for each iteration.

$result = [];
foreach ($arr as $v) {
    // Initialize the person
    if (!isset($result[$v['name']])) {
        $result[$v['name']] = ["name" => $v['name'], "count_employee" => 0, "count_warehouse" => 0];
    }
    // Add values
    if (isset($v['count_employee']))
        $result[$v['name']]['count_employee'] += $v['count_employee'];
    if (isset($v['count_warehouse']))
        $result[$v['name']]['count_warehouse'] += $v['count_warehouse'];
}
// print_r($result);

Upvotes: 4

Related Questions