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.
I have no idea why there is any need to call array_filter()
, array_column()
, array_search()
, array_merge()
, or array_unique()
. Grouping the related data is matter of assigning temporary first-level keys, then unconditionally declaring or pushing the row data into the group. If you want to re-index the result array, just call array_values()
after the loop finishes.
Code: ( Demo )
$array = [
['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']
];
$result = [];
foreach ($array as $row) {
$result[$row['invoice_id']]['invoice_id'] = $row['invoice_id'];
$result[$row['invoice_id']]['group'][] = $row;
}
var_export(array_values($result));
// output: exactly as desired in the question
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'))
));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.