<?php
function treeifyDbRows(array $inputArray, array $branchRules): array
{
$output = [];
if ($branchRules) {
$ruleSet = array_shift($branchRules);
$masterRule = $ruleSet[0];
$branchChildren = [];
foreach ($inputArray as $index => $element) {
$branchChildren[] = $element;
//coalesce null to 0
if (($inputArray[$index + 1][$masterRule] ?? 0) !== $element[$masterRule]) {
$branch = [];
foreach ($ruleSet as $rule) {
$branch[$rule] = $branchChildren[0][$rule];
}
$children = treeifyDbRows($branchChildren, $branchRules);
if ($children) {
$branch['children'] = $children;
}
$output[] = $branch;
$branchChildren = [];
}
}
}
return $output;
}
$data =
[
[
"countryID" => 1,
"countryName" => "USA",
"regionID" => 10,
"regionName" => "Indiana",
"cityID" => 100,
"cityName"=> "Indianapolis",
],
[
"countryID" => 1,
"countryName" => "USA",
"regionID" => 10,
"regionName" => "Indiana",
"cityID" => 101,
"cityName"=> "Bloomington",
],
[
"countryID" => 1,
"countryName" => "USA",
"regionID" => 11,
"regionName" => "Michigan",
"cityID" => 102,
"cityName"=> "Lansing",
],
[
"countryID" => 2,
"countryName" => "Canada",
"regionID" => 12,
"regionName" => "Ontario",
"cityID" => 103,
"cityName"=> "Toronto",
],
[
"countryID" => 2,
"countryName" => "Canada",
"regionID" => 12,
"regionName" => "Ontario",
"cityID" => 104,
"cityName"=> "Ottawa",
],
[
"countryID" => 2,
"countryName" => "Canada",
"regionID" => 12,
"regionName" => "Ontario",
"cityID" => 105,
"cityName"=> "Windsor",
],
[
"countryID" => 2,
"countryName" => "Canada",
"regionID" => 25,
"regionName" => "Quebec",
"cityID" => 106,
"cityName"=> "Montreal",
],
];
$rules =
[
["countryID", "countryName"],
["regionID", "regionName"],
["cityID", "cityName"],
];
$results = treeifyDbRows($data, $rules);
var_dump($results);
- Output for 7.4.0 - 7.4.33, 8.0.1 - 8.0.30, 8.1.0 - 8.1.28, 8.2.0 - 8.2.18, 8.3.0 - 8.3.6
- array(2) {
[0]=>
array(3) {
["countryID"]=>
int(1)
["countryName"]=>
string(3) "USA"
["children"]=>
array(2) {
[0]=>
array(3) {
["regionID"]=>
int(10)
["regionName"]=>
string(7) "Indiana"
["children"]=>
array(2) {
[0]=>
array(2) {
["cityID"]=>
int(100)
["cityName"]=>
string(12) "Indianapolis"
}
[1]=>
array(2) {
["cityID"]=>
int(101)
["cityName"]=>
string(11) "Bloomington"
}
}
}
[1]=>
array(3) {
["regionID"]=>
int(11)
["regionName"]=>
string(8) "Michigan"
["children"]=>
array(1) {
[0]=>
array(2) {
["cityID"]=>
int(102)
["cityName"]=>
string(7) "Lansing"
}
}
}
}
}
[1]=>
array(3) {
["countryID"]=>
int(2)
["countryName"]=>
string(6) "Canada"
["children"]=>
array(2) {
[0]=>
array(3) {
["regionID"]=>
int(12)
["regionName"]=>
string(7) "Ontario"
["children"]=>
array(3) {
[0]=>
array(2) {
["cityID"]=>
int(103)
["cityName"]=>
string(7) "Toronto"
}
[1]=>
array(2) {
["cityID"]=>
int(104)
["cityName"]=>
string(6) "Ottawa"
}
[2]=>
array(2) {
["cityID"]=>
int(105)
["cityName"]=>
string(7) "Windsor"
}
}
}
[1]=>
array(3) {
["regionID"]=>
int(25)
["regionName"]=>
string(6) "Quebec"
["children"]=>
array(1) {
[0]=>
array(2) {
["cityID"]=>
int(106)
["cityName"]=>
string(8) "Montreal"
}
}
}
}
}
}
preferences:
129.43 ms | 410 KiB | 121 Q