To flatten a JSON like this:
{
"addresses" : [
{
"line1" : "123 Livingstone Rd",
"id" : 23444555,
"addressSummaryType": "Building",
"subAddresses": {
"Level1": [
{
"line1" : "Level 2",
"id" : 266887373,
"Level2": [
{
"line1": "Suite 201",
"id" : 276888890
}
]
}
]
}
},
{
"addressSummaryType": "Building",
"line1" : "124 Livingstone Rd",
"id" : 2562672
}
]
}
to:
array(2) {
["id"]=>
int(23444555)
["address"]=>
string(18) "123 Livingstone Rd"
}
array(2) {
["id"]=>
int(266887373)
["address"]=>
string(26) "Level 2 123 Livingstone Rd"
}
array(2) {
["id"]=>
int(276888890)
["address"]=>
string(36) "Suite 201 Level 2 123 Livingstone Rd"
}
array(2) {
["id"]=>
int(2562672)
["address"]=>
string(18) "124 Livingstone Rd"
}
I used the following code:
foreach(flattenAddress($addressObj->addresses) as $flattenedAddress) {
var_dump($flattenedAddress);
}
function flattenAddress($addresses, $baseAddress = '', $level = 0)
{
foreach ($addresses as $address) {
$nextLevel = "Level" . ($level + 1);
if (property_exists($address, "addressSummaryType")) { //root
$baseAddress = $address->line1;
yield ["id" => $address->id, "address" => $baseAddress];
if (property_exists($address, "subAddresses")) {
yield from flattenAddress($address->subAddresses->{$nextLevel}, $baseAddress, ($level + 1));
continue; // recurse don't reset level
}
} else { //subaddresses
$subAddress = $address->line1 . " " . $baseAddress;
yield ["id" => $address->id, "address" => $subAddress];
if (property_exists($address, $nextLevel)) {
yield from flattenAddress($address->{$nextLevel}, $subAddress, ($level + 1));
continue; // recurse don't reset level
}
}
$level = 0; //reset for next root
}
}