I have a JSON file with a single array and all elements in the same level. Each of the entries has a “level” attribute between 1 and 4. I want to have a nested array in the end which has all level 4 inside the level 3, all level 3 inside the level 2, all level 2 inside the level 1.
The JSON example is like this:
[{“text e”:”Test”,”id”:1073,”level”:1,”chapter”:”1″}, {“text e”:”Test 2″,”id”:1073,”level”:2,”chapter”:”1.1″}, {“text e”:”Test 3″,”id”:1063,”level”:2,”chapter”:”1.2″}, {“text e”:”Test 4″,”id”:1031,”level”:3,”chapter”:”1.2.1″}, {“text e”:”Test 5″,”id”:1334,”level”:4,”chapter”:”1.2.1.1″}, {“text e”:”Test 6″,”id”:1127,”level”:2,”chapter”:”1.3″}, {“text e”:”Test 7″,”id”:1092,”level”:2,”chapter”:”1.4″}, {“text e”:”Test 8″,”id”:1012,”level”:1,”chapter”:”2″}]
<?php $json = json_decode(file_get_contents("menuitems.json"), true); $newArr = array(); $keyLevel1 = 0; $keyLevel2 = 0; $keyLevel3 = 0; $keyLevel4 = 0; foreach ($json as $key => $item) { if ($item['level'] == 1) { $newArr[$keyLevel1] = $item; $keyLevel1 = $keyLevel1 + 1; $keyLevel2 = 0; $keyLevel3 = 0; $keyLevel4 = 0; } else if ($item['level'] == 2) { $newArr[$keyLevel1][$keyLevel2] = $item; $keyLevel2 = $keyLevel2 + 1; $keyLevel3 = 0; $keyLevel4 = 0; } else if ($item['level'] == 3) { $newArr[$keyLevel1][$keyLevel2][$keyLevel3] = $item; $keyLevel3 = $keyLevel3 + 1; $keyLevel4 = 0; } else if ($item['level'] == 4) { $newArr[$keyLevel1][$keyLevel2][$keyLevel3][$keyLevel4] = $item; $keyLevel4 = $keyLevel4 + 1; } } echo json_encode($newArr); ?>
This code seems to work for the first level but the level 2 of the last item are written in the last object and they’re not nesting. What am I doing wrong?
Advertisement
Answer
This is a classic off-by-one error. You’re incrementing all of the keyLevel variables at the wrong time. The simplest fix might be to always (re-)initialize them all to -1, and then increment before using, for instance, the first “if” would become:
$keyLevel1 = -1; ... if ($item['level'] == 1) { $keyLevel1 = $keyLevel1 + 1; $newArr[$keyLevel1] = $item; $keyLevel2 = -1; $keyLevel3 = -1; $keyLevel4 = -1; }
That way, $keyLevel1 will have the correct value when you process the subsequent level 2, 3, and 4 items.