Reputation: 1503
I have an array with common product code & product name. For each product_code can have two types of cha_sty_id i.e push or pull. This is an array structure I have.
$array = [
0 => [
"product_code" => "67021687",
"product_name" => "Spaces",
"cha_sty_id" => "PUSH",
"chs_name" => "WF"
],
1 => [
"product_code" => "67021687",
"product_name" => "Spaces",
"cha_sty_id" => "PUSH",
"chs_name" => "WFR"
],
2 => [
"product_code" => "67021687",
"product_name" => "Spaces",
"cha_sty_id" => "PUSH",
"chs_name" => "STK Food"
],
3 => [
"product_code" => "67021687",
"product_name" => "Spaces",
"cha_sty_id" => "PULL",
"chs_name" => "4 Stars"
],
4 => [
"product_code" => "67021687",
"product_name" => "Spaces",
"cha_sty_id" => "PULL",
"chs_name" => "5 Stars"
],
5 => [
"product_code" => "67021687",
"product_name" => "Spaces",
"cha_sty_id" => "PULL",
"chs_name" => "Modern Thai"
],
6 => [
"product_code" => "67021687",
"product_name" => "Spaces",
"cha_sty_id" => "PULL",
"chs_name" => "BBQ Buffet"
],
7 => [
"product_code" => "67021687",
"product_name" => "Spaces",
"cha_sty_id" => "PULL",
"chs_name" => "Chinese"
]
];
Now I want result something like:
0 => [
'product_code' => 67021687,
'product_name' => 'Spaces.
'push => array(....ALL chs_name for push),
'pull' => array with chs_name for pull
]
I have tried some code
$list = array();
foreach ($records as $data) {
$list[$data['product_code']][] = $data;
if($data['cha_sty_id'] == 'PUSH') {
$list[$data['product_code']]['push'] = $data['chs_name'];
} else {
$list[$data['product_code']]['pull'] = $data['chs_name'];
}
}
But I could not solve it. Can anybody pls help me.
Thank You.
Upvotes: 0
Views: 86
Reputation: 47894
There is no need for any conditional expressions while partially pivoting your data into groups. Use the product_code
values as temporary first level keys and use the cha_sty_id
values as dynamic second level keys. Re-index the result array after the loop finishes with array_values()
.
One approach uses a body-less foreach as explained here.
Code: (Demo)
$result = [];
foreach (
$array
as
[
'product_code' => $productCode,
'cha_sty_id' => $id,
'product_code' => $result[$code]['product_code'],
'product_name' => $result[$code]['product_name'],
'chs_name' => $result[$code][strtolower($id)][]
]
);
var_export(array_values($result));
A more traditional style is to group and pivot inside the body of the loop.
Code: (Demo)
$result = [];
foreach ($array as $row) {
$result[$row['product_code']]['product_code'] = $row['product_code'];
$result[$row['product_code']]['product_name'] = $row['product_name'];
$result[$row['product_code']][strtolower($row['cha_sty_id'])][] = $row['chs_name'];
}
var_export(array_values($result));
Due to the fact that the group logic is possibly going to return an array size that differs from the input array, array_reduce()
is the most appropriate functional iterator for this task.
Code: (Demo)
var_export(
array_values(
array_reduce(
$array,
function($result, $row) {
$result[$row['product_code']]['product_code'] = $row['product_code'];
$result[$row['product_code']]['product_name'] = $row['product_name'];
$result[$row['product_code']][strtolower($row['cha_sty_id'])][] = $row['chs_name'];
return $result;
},
[]
)
)
);
All techniques above produce the exact same result.
Upvotes: 0
Reputation: 6388
You can use array_walk
,array_push
$res = [];
array_walk($array, function($v, $k) use (&$res){
if(in_array($v['product_code'], array_column($res, 'product_code'))){
array_push($res[$v['product_code']]["push"], $v['chs_name']);
array_push($res[$v['product_code']]["pull"], $v['chs_name']);
}else{
$res[$v['product_code']] = [
"product_code" => $v['product_code'],
"product_name" => $v['product_name'],
"push" => [$v['chs_name']],
"pull" => [$v['chs_name']]
];
}
});
echo '<pre>';
print_r(array_values($res));
Upvotes: 1
Reputation: 11642
How about this modify your foreach
loop to this:
$list = array();
foreach ($records as $data) {
$code = $data['product_code']; // as key
if (!isset($list[$code])) { // set new array if not exist
$list[$code] = array("product_code" => $code, "product_name" => $data['product_name'], "push" => [], "pull" => []);
}
$subKey = strtolower($data['cha_sty_id']); // get push / pull as new subkey
$list[$code][$subKey][] = $data['chs_name']; // append to the array
}
You can use array_values
to remove the code keys from $list
after the loop if not needed
Upvotes: 1