I have an array mentioned below.
$array = array(
\'0\' => array(
\'names\' => array(0 => \'Apple\'),
\'group\' => 1
By simply using the group
values as temporary associative keys, you can swiftly determine (while iterating) if you should store the whole row of data, or just append the names
value to an existing subarray.
*if your project data may contain input subarrays with more than one names
value, you should update your question to clarify this possibility. (Fringe Demo) (Fringe Demo2)
Code: (Demo)
foreach ($array as $row) {
if (!isset($result[$row['group']])) {
$result[$row['group']] = $row;
} else {
$result[$row['group']]['names'][] = $row['names'][0];
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'names' =>
array (
0 => 'Apple',
1 => 'Mango',
2 => 'Grapes',
),
'group' => 1,
),
1 =>
array (
'names' =>
array (
0 => 'Tomato',
1 => 'Potato',
),
'group' => 2,
),
)
You can use array_values()
to remove the temporary associative keys from the result array.
<?php
//initialize our array
$array = array(
'0' => array(
'names' => array(0 => 'Apple'),
'group' => 1
),
'1' => array(
'names' => array(0 => 'Mango'),
'group' => 1
),
'2' => array(
'names' => array(0 => 'Grapes'),
'group' => 1
),
'3' => array(
'names' => array(0 => 'Tomato'),
'group' => 2
),
'4' => array(
'names' => array(0 => 'Potato'),
'group' => 2
)
);
//result will be here
$result = array();
foreach ($array as $key => $value) {
//check if we have keys group or names to avoid errors
if(!isset($value['group']) || !isset($value['names']))
continue;
//make a key in result array if its not exist
if(!isset($result[$value['group']]))
{
$result[$value['group']] = $value['names'];
}
else
{
//add a values to key if it exists
$result[$value['group']] = array_merge($result[$value['group']],
$value['names']);
//filter same values
$result[$value['group']] = array_values(array_unique($result[$value['group']]));
}
}
print_r($result);
A perfect usage example for the PHP function array_reduce():
$array = array_values(
array_reduce(
$array,
function (array $carry, array $item) {
// Extract the group name into a variable for readability
// and speed; it is used several times velow
$key = $item['group'];
// Initialize the group if it is the first entry in this group
if (! array_key_exists($key, $carry)) {
$carry[$key] = array(
'names' => array(),
'group' => $key,
);
}
// Add the new names to the group in the output array
$carry[$key]['names'] = array_merge($carry[$key]['names'], $item['names']);
// Return the partial result
return $carry;
},
array()
)
);
The code uses array_reduce() to iteratively build a new array that contains the expected values.
The callback function creates the group, if needed, then merges the names of the processed item into the existing group in the resulting array.
The array generated using array_reduce()
is indexed using the values of group
, in the order they appear in the input array. For the posted array, they keys will be 1
and 2
. If you don't care about the keys then remove the call to array_values()
to gain a little improvement in speed and readability.
The function array_values() drops the keys and returns an array indexed using sequential numerical keys starting with zero (as the one listed in the question).
You could iterate the array and store everything in a separate array to the group. Afterwards, you can create the output array in the format you want it, like so:
$groups = array();
foreach($array as $subArray) {
if (!array_key_exists($subArray['group'], $groups)) {
$groups[$subArray['group']] = array();
}
$groups[$subArray['group']] = array_merge($groups[$subArray['group']], $subArray['names']);
}
$result = array();
foreach($groups as $groupId => $group) {
$result[] = array(
'names' => $group,
'group' => $groupId,
);
}
print_r($result);