Reputation: 179
I have an array like this one:
$array = [
['Categoria' => 'example', 'Servico' => 'name1'],
['Categoria' => 'example', 'Servico' => 'name2'],
['Categoria' => 'example', 'Servico' => 'name3'],
['Categoria' => 'example2', 'Servico' => 'name4'],
['Categoria' => 'example2', 'Servico' => 'name5'],
['Categoria' => 'example2', 'Servico' => 'name6'],
['Categoria' => 'example3', 'Servico' => 'name7'],
['Categoria' => 'example3', 'Servico' => 'name8'],
['Categoria' => 'example3', 'Servico' => 'name9']
];
I need to transform this on something like:
[
[
'Servico' => 'example',
'children' => [
['Servico' => 'name1'],
['Servico' => 'name2'],
['Servico' => 'name3'],
]
],
[
'Servico' => 'example2',
'children' => [
['Servico' => 'name4'],
['Servico' => 'name5'],
['Servico' => 'name6'],
]
],
[
'Servico' => 'example3',
'children' => [
['Servico' => 'name7'],
['Servico' => 'name8'],
['Servico' => 'name9'],
]
],
]
I have read this topic and I successfully have grouped my array, but I couldn't find a way to format the array in a way I have Servico
and children
on each object.
Someone have any ideas?
Upvotes: 1
Views: 74
Reputation: 48000
There is no need for multiple loops or conditions or counters here.
Every group's Servico
value ($row['Categoria']
) can be safely overwritten on each iteration.
Each new $row['Servico']
value is to be unconditionally pushed into the respective children
subarray.
After using $row['Categoria']
to provide temporary grouping keys in the result array, re-index the result with array_values()
.
*Note: I am electing to flatten the data structure of children
to be an indexed array. I don't see any value in creating single-element associative arrays for each entry. If you DO want that then push ['Servico' => $row['Servico']]
into the children
.
Functional-style with array_reduce()
: (Demo)
var_export(
array_values(
array_reduce(
$array,
function ($carry, $row) {
$carry[$row['Categoria']]['Servico'] = $row['Categoria'];
$carry[$row['Categoria']]['children'][] = $row['Servico'];
return $carry;
}
)
)
);
Classic foreach()
: (Demo)
$result = [];
foreach ($array as $row) {
$result[$row['Categoria']]['Servico'] = $row['Categoria'];
$result[$row['Categoria']]['children'][] = $row['Servico'];
}
var_export(array_values($result));
Upvotes: 1
Reputation: 501
just assume $array is your array
$i=0;
$temp = array();
foreach ($array as $arr)
{
if($i !=0 && $arr['Categoria'] == $temp[$i-1]['Servico']){
$temp[$i-1]['children']['Servico'] = $arr['Servico'];
}else{
$temp[$i]['Servico'] =$arr['Categoria'];
$temp[$i]['children']['Servico'] = $arr['Servico'];
$i++;
}
}
//$temp is your new array
Upvotes: 0
Reputation: 23968
You can foreach the array and build a new array with the structure you want.
$new =array();
Foreach($A as $item){
If(!isset($new[$item['Categoria']])) $new[$item['Categoria']] = array(); // create array of not set
$new[$item['Categoria']][] = $item['Servico']; // add servico item to array
}
This loops each item if it does not find the subarray it will create it.
Then add the 'name' values in the subarray.
Edit, see now that you want your output array to be named B, just change 'new' to 'B' in the code.
Upvotes: 0