My input is:
$item = [
['invoice_id' => '72,', 'item' => 'SN00001'],
['invoice_id' => '73,', 'item' => 'SN00002'],
['invoice_id' => '73,', 'item' => 'SN00003'],
['invoice_id' => '73,', 'item' => 'SN00004'],
['invoice_id' => '74,', 'item' => 'SN00005'],
['invoice_id' => '74,', 'item' => 'SN00006']
];
I want to re-group it with the invoice_id
like this
[0] => Array
(
[invoice_id] => 72
[group] => Array
(
[0] => Array
(
[invoice_id] => 72,
[item] => SN00001
)
)
)
[1] => Array
(
[invoice_id] => 73
[group] => Array
(
[0] => Array
(
[invoice_id] => 73,
[item] => SN00002
)
[1] => Array
(
[invoice_id] => 73,
[item] => SN00003
)
[2] => Array
(
[invoice_id] => 73,
[item] => SN00004
)
)
)
[2] => Array
(
[invoice_id] => 74
[group] => Array
(
[0] => Array
(
[invoice_id] => 74,
[item] => SN00005
)
[1] => Array
(
[invoice_id] => 74,
[item] => SN00006
)
)
)
This is what I did so far
$items = [];
foreach($item as $k => $val){
if(empty($items)){
// if first row
$items[$k]['invoice_id'] = $val['invoice_id'];
$items[$k]['group'] = [$val];
} else {
if(!empty($items)){
foreach($items as $key => $value){
if($value['invoice_id'] == $val['invoice_id']){
// if same invoice_id merge the value into the group
$items[$key]['group'] = array_merge($items[$key]['group'], [$val]);
} else {
// else create a array group
$items[$k]['invoice_id'] = $val['invoice_id'];
$items[$k]['group'] = [$val];
}
}
}
}
}
Sample: https://onecompiler.com/php/3y2hgzk79
The issue with my current codes is, it will create a duplicate item in some group. I was trying to use array_search
and array_column
but it didn't go as expected result so I switched to foreach
instead and here I am. Any help will be much appreciated.
Here's a fairly concise solution based on some built-in PHP array handling functions (array_map
, array_filter
, array_unique
and array_column
). It uses array_column
and array_unique
to get a list of distinct invoice_id
values, then array_map
to generate the output, filtering the input array for each entry based on whether the invoice_id
values match:
$items = array_map(function ($inv_id) use ($item) {
return array('invoice_id' => $inv_id,
'group' => array_filter($item,
function ($itm) use ($inv_id) {
return $itm['invoice_id'] == $inv_id;
})
);
}, array_unique(array_column($item, 'invoice_id'))
);
Output:
Array
(
[0] => Array
(
[invoice_id] => 72,
[group] => Array
(
[0] => Array
(
[invoice_id] => 72,
[item] => SN00001
)
)
)
[1] => Array
(
[invoice_id] => 73,
[group] => Array
(
[1] => Array
(
[invoice_id] => 73,
[item] => SN00002
)
[2] => Array
(
[invoice_id] => 73,
[item] => SN00003
)
[3] => Array
(
[invoice_id] => 73,
[item] => SN00004
)
)
)
[4] => Array
(
[invoice_id] => 74,
[group] => Array
(
[4] => Array
(
[invoice_id] => 74,
[item] => SN00005
)
[5] => Array
(
[invoice_id] => 74,
[item] => SN00006
)
)
)
)
Note that internal array numbering does not start at 0
; if you need that then add array_values
to re-index in the appropriate places:
$items = array_values(array_map(function ($inv_id) use ($item) {
return array('invoice_id' => $inv_id,
'group' => array_values(array_filter($item,
function ($itm) use ($inv_id) {
return $itm['invoice_id'] == $inv_id;
}))
);
}, array_unique(array_column($item, 'invoice_id'))
));