Skip to content
Advertisement

PHP – How To Grouping if value same in array

This my array example

Array
(
  [0] => Array ( [_id] => 5f76b1788ee23077dccd1a2c [product] => Array ( [0] => Array ( [_id] => 5d0391a4a72ffe76b8fcc610 ) ) [count] => 1 )
  [1] => Array ( [_id] => 5f76b6288ee2300700cd1a3a [product] => Array ( [0] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) ) [count] => 1 )
  [2] => Array ( [_id] => 5f76d2488ee23083d3cd1a4a [product] => Array ( [0] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) ) [count] => 1) 
)

And i want to group if product value same, like this,

Array
(
  [0] => Array ( [_id] => 5f76b1788ee23077dccd1a2c [product] => Array ( [0] => Array ( [_id] => 5d0391a4a72ffe76b8fcc610 ) ) [count] => 1 )
  [1] => Array ( [_id] => 5f76b6288ee2300700cd1a3a [product] => Array ( [0] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) ) [count] => 2 )
)

Advertisement

Answer

It makes no sense to retain the first level ids since you are arbitrarily trashing some of the first level ids (damaging the relationships) during the merging process.

Instead I recommend that you only isolate the data that is accurately related.

If this output does not serve your needs, then I’ll ask for further question clarification.

By assigning temporary keys to your output array, the output array also acts as a lookup array by which you can swiftly check for uniqueness. The “null coalescing operator” (??) sets a fallback value of 0 when an id is encountered for the first time — this prevents generating any warnings regarding undeclared keys.

Code: (Demo)

$array = [
    ['_id' => '5f76b1788ee23077dccd1a2c', 'product' => ['_id'=>'5d0391a4a72ffe76b8fcc610'], 'count'=> 1],
    ['_id' => '5f76b6288ee2300700cd1a3a', 'product' => ['_id'=>'5d0391b6a72ffe76b8fcc611'], 'count'=> 1],
    ['_id' => '5f76d2488ee23083d3cd1a4a', 'product' => ['_id'=>'5d0391b6a72ffe76b8fcc611'], 'count'=> 1]
];

$productCounts = [];
foreach ($array as $item) {
    $productId = $item['product']['_id'];
    $productCounts[$productId] = ($productCounts[$productId] ?? 0) + $item['count'];
}

var_export($productCounts);

Output:

array (
  '5d0391a4a72ffe76b8fcc610' => 1,
  '5d0391b6a72ffe76b8fcc611' => 2,
)

If you insist of the desired output in your question, then it can be as simple and efficient as this…

Code: (Demo)

$result = [];
foreach ($array as $item) {
    $productId = $item['product']['_id'];
    if (!isset($result[$productId])) {
        $result[$productId] = $item;
    } else {
        $result[$productId]['count'] += $item['count'];
    }
}

var_export(array_values($result));

Output:

array (
  0 => 
  array (
    '_id' => '5f76b1788ee23077dccd1a2c',
    'product' => 
    array (
      '_id' => '5d0391a4a72ffe76b8fcc610',
    ),
    'count' => 1,
  ),
  1 => 
  array (
    '_id' => '5f76b6288ee2300700cd1a3a',
    'product' => 
    array (
      '_id' => '5d0391b6a72ffe76b8fcc611',
    ),
    'count' => 2,
  ),
)
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement