I’ve got a multidimensional array containing some id’s, stored in keys called ‘name’. Each entry can have other sub-arrays, containing other id’s. The array is dynamic; the depth and entries are unknown. Here is an example:
Array
(
[0] => Array
(
[name] => test1
[subs] => Array
(
[0] => Array
(
[name] => test2
)
[1] => Array
(
[name] => test3
[subs] => Array
(
[name] => test4
)
)
)
)
[1] => Array
(
[name] => test5
)
)
Now I want to convert this multidimensional array to a ‘flat’ array, while keeping hold of the depth. The scope of the new array is some kind of table of contents, where the key represents a chapter and the value an id. For example, ‘test4’ should be chapter 1.2.1, ‘test2’ should be 1.1 and ‘test5’ should be chapter 2. Each level deeper means the entry is a child of the parent level. Therefore I have to store every previous depth-‘level’ while looping the array. So far I haven’t found a way to do this.
QUESTION UPDATE:
I’ve got the first part working. Now I want to add new chapters to the array, and have the chapter numbers of the existing entries update themselves. The array now looks like this:
Array
(
[1] => test1
[1.1] => test2
[1.2] => test3
[1.2.1] => test4
[2] => test5
)
So now I would like to add chapter ‘test6’ as first-child of 1.2, which means the current 1.2.1 would become 1.2.2 and the new child will be 1.2.1 instead.
Code:
Output:
Demo
EDIT
These two (plus one supporting) functions allow you add and remove chapters from the input array by chapter reference. Then, you can recalculate the TOC from the new structure.
The best way to demonstrate how they work is with an example. Say we start with the array structure above, which is held in a variable called
$structure. As we know, our resulting TOC array looks like this:Now, we decide we want to remove chapter
1.2and all it’s sub-chapters – we can do this:Now lets say we want to add a chapter called
test6as chapter1.1, andtest2will be re-indexed to1.2– we’ll be working with the result of the above example for this one:OK, seems fairly simple. But what if we wanted to move a sub-chapter, so it was at the top level of the tree? Let’s go back to our original version of
$structureto demonstrate this – we’ll move chapter1.2, so that it is now chapter3:Hopefully I’ve explained it well enough there.
chapter_exists()returns a boolean. Fairly self explanatory as to what it means, if feel. Pass the$structurearray as the first parameter, and the chapter ID you want to check as the second. This function is required, as it is used by the other two internally.add_chapter()returns a boolean, so you can test whether the operation was successful. It will fail if the parent of the chapter doesn’t exist – for example, if you try to add1.2.1when1.2hasn’t been defined, it won’t work. If you add a chapter that already exists, all the chapter numbers at that level will be shifted up by 1.remove_chapter()will return the item that was removed on success (i.e. an array) or booleanFALSEon failure – it will fail if you try and remove a chapter that doesn’t exist.NB: I had to make heavy use of
eval()for this, in order to accommodate for arbitrary level depth. I hate to use it, but I couldn’t think of any other way – if anyone reading this has any bright ideas about alternative approaches (preferably that don’t involve some nightmarish looping structure), please let me know…