Reputation: 3073
I have a flat associative array which may contain duplicate values.
Array (
[for-juniors] => product_category
[for-men] => product_category
[coats] => product_category
[for-women] => product_category
[7-diamonds] => brand
)
I need to restructure the data to store the original values as new keys and the original keys pushed into subarrays associated with the new keys.
array(
'product_category' => array(
'for-juniors',
'for-men',
'coats',
'for-women'
),
'brand' => array(
'7-diamonds'
)
);
Upvotes: 4
Views: 1644
Reputation: 47991
Because within a foreach()
loop, the values are declared BEFORE the keys, you can actually populate the new data structure with a body-less foreach()
loop.
Code: (Demo)
$array = [
'for-juniors' => 'product_category',
'for-men' => 'product_category',
'coats' => 'product_category',
'for-women' => 'product_category',
'7-diamonds' => 'brand'
];
$grouped = [];
foreach ($array as $grouped[$group][] => $group);
var_export($grouped);
Output:
array (
'product_category' =>
array (
0 => 'for-juniors',
1 => 'for-men',
2 => 'coats',
3 => 'for-women',
),
'brand' =>
array (
0 => '7-diamonds',
),
)
Upvotes: 1
Reputation: 1851
This'll do:
function array_flip_safe(array $array) : array
{
return array_reduce(array_keys($array), function ($carry, $key) use (&$array) {
$carry[$array[$key]] ??= []; // PHP 7.0 - ^7.3: $carry[$array[$key]] = $carry[$array[$key]] ?? [];
$carry[$array[$key]][] = $key;
return $carry;
}, []);
}
The callback creates an empty array if the array doesn't already exist. Then it appends current iteration's $key
($value
of array_keys($array)
) to that array.
Here's an example for better understanding:
$businessHours = [
'mo' => '13:00 - 16:00',
'tu' => '8:00 - 12:00',
'we' => '13:00 - 16:00',
'th' => '8:00 - 12:00',
'fr' => '13:00 - 16:00',
'sa' => '',
'su' => '',
];
$flipped = array_flip_safe($businessHours);
ray($flipped);
(or var_dump
, var_export
, etc.) outputs:
array:3 [▼
"13:00 - 16:00" => array:3 [▼
0 => "mo"
1 => "we"
2 => "fr"
]
"8:00 - 12:00" => array:2 [▼
0 => "tu"
1 => "th"
]
"" => array:2 [▼
0 => "sa"
1 => "su"
]
]
Note that the order of inner arrays' values is the same as the order of original array's keys.
Upvotes: 0
Reputation: 522451
$grouped = array();
foreach ($input as $choice => $group) {
$grouped[$group][] = $choice;
}
var_dump($grouped);
Upvotes: 6