I've recently written a function that allows me to take a flat array and convert it into a multidimensional array by a specific key in the array.
public function groupArray($arr, $group, $preserveGroupKey = false, $preserveSubArrays = false) {
$temp = array();
foreach($arr as $key => $value) {
$groupValue = $value[$group];
if(!$preserveGroupKey)
{
unset($arr[$key][$group]);
}
if(!array_key_exists($groupValue, $temp)) {
$temp[$groupValue] = array();
}
if(!$preserveSubArrays){
$data = count($arr[$key]) == 1? array_pop($arr[$key]) : $arr[$key];
} else {
$data = $arr[$key];
}
$temp[$groupValue][] = $data;
}
return $temp;
}
Breakdown
function groupArray($arr, $group, $preserveGroupKey = false, $preserveSubArrays = false)
This function accepts 2 to 4 parameters.
- The flat array you want to group (array)
- The key you want to group by (string/int)
- Option to preserve the group key in the output of each sub array (Boolean)
- Option to preserve sub arrays. If only 1 key exists in each sub array, the function will store just the single value for each row instead of an array (Boolean)
The first parameter is the array itself, the second parameter is the key that you want to group by, and the 3rd (optional) parameter is a boolean that tells the function if you want to preserve the group key in the sub arrays.
Examples
Let's use this dataset for examples:
$arr = [
0 => [
"group" => "group1",
"name" => "Bob",
],
1 => [
"group" => "group1",
"name" => "Randy",
],
2 => [
"group" => "group1",
"name" => "Susan",
],
3 => [
"group" => "group2",
"name" => "Larry",
],
4 => [
"group" => "group2",
"name" => "David",
],
5 => [
"group" => "group3",
"name" => "Perry",
],
];
groupArray($arr, "group");
Will return
Array
(
[group1] => Array
(
[0] => Bob
[1] => Randy
[2] => Susan
)
[group2] => Array
(
[0] => Larry
[1] => David
)
[group3] => Array
(
[0] => Perry
)
)
groupArray($arr, "group", true);
will return
Array
(
[group1] => Array
(
[0] => Array
(
[group] => group1
[name] => Bob
)
[1] => Array
(
[group] => group1
[name] => Randy
)
[2] => Array
(
[group] => group1
[name] => Susan
)
)
[group2] => Array
(
[0] => Array
(
[group] => group2
[name] => Larry
)
[1] => Array
(
[group] => group2
[name] => David
)
)
[group3] => Array
(
[0] => Array
(
[group] => group3
[name] => Perry
)
)
)
groupArray($arr, "group", false, true);
Will return
Array
(
[group1] => Array
(
[0] => Array
(
[name] => Bob
)
[1] => Array
(
[name] => Randy
)
[2] => Array
(
[name] => Susan
)
)
[group2] => Array
(
[0] => Array
(
[name] => Larry
)
[1] => Array
(
[name] => David
)
)
[group3] => Array
(
[0] => Array
(
[name] => Perry
)
)
)