Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6728807
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T10:12:50+00:00 2026-05-26T10:12:50+00:00

I’ve got a multidimensional array containing some id’s, stored in keys called ‘name’. Each

  • 0

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.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T10:12:51+00:00Added an answer on May 26, 2026 at 10:12 am

    Code:

    // Mmmm... functiony goodness
    function array_to_toc ($in, &$out, $level = '') {
      if (!$level) $out = array(); // Make sure $out is an empty array at the beginning
      foreach ($in as $key => $item) { // Loop items
        $thisLevel = ($level) ? "$level.".($key + 1) : ($key + 1); // Get this level as string
        $out[$thisLevel] = $item['name']; // Add this item to $out
        if (isset($item['subs']) && is_array($item['subs']) && count($item['subs'])) array_to_toc($item['subs'],$out,$thisLevel); // Recurse children of this item
      }
    }
    
    // Here is your test data (slightly modified - I think you stated it wrong in the question)
    $array = array (
      0 => array (
        'name' => 'test1',
        'subs' => array (
          0 => array (
            'name' => 'test2'
          ),
          1 => array (
            'name' => 'test3',
            'subs' => array (
              0 => array (
                'name' => 'test4'
              )
            )
          )
        )
      ),
      1 => array (
        'name' => 'test5'
      )
    );
    
    // $result is passed by reference and will hold the output after the function has run
    $result = array();
    array_to_toc($array, $result);
    
    print_r($result);
    

    Output:

    Array
    (
        [1] => test1
        [1.1] => test2
        [1.2] => test3
        [1.2.1] => test4
        [2] => test5
    )
    

    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.

    function chapter_exists ($array, $chapterId) {
      $chapterParts = explode('.',$chapterId);
      foreach ($chapterParts as &$chapter) $chapter--;
      $lastId = array_pop($chapterParts);
      return eval('return isset($array['.implode("]['subs'][",$chapterParts).((count($chapterParts)) ? "]['subs'][" : '')."$lastId]);");
    }
    
    function add_chapter (&$array, $chapterId, $item) {
      $chapterParts = explode('.',$chapterId);
      foreach ($chapterParts as &$chapter) $chapter--; // Decrement all the values
      $lastId = array_pop($chapterParts);
      if (count($chapterParts) && !chapter_exists($array, implode('.',$chapterParts))) return FALSE; // Return FALSE if the level above the chapter we are adding doesn't exist
      if (chapter_exists($array, $chapterId)) { // See if the chapter reference already exists
        eval('array_splice($array'.((count($chapterParts)) ? '['.implode("]['subs'][",$chapterParts)."]['subs']" : '').",$lastId,0,array(\$item));"); // Insert an item
      } else {
        eval('$array['.implode("]['subs'][",$chapterParts).((count($chapterParts)) ? "]['subs'][" : '')."$lastId] = \$item;"); // Insert an item
      }
      return TRUE;
    }
    
    function remove_chapter (&$array, $chapterId) {
      $chapterParts = explode('.',$chapterId);
      foreach ($chapterParts as &$chapter) $chapter--; // Decrement all the values
      $lastId = array_pop($chapterParts);
      return (chapter_exists($array, $chapterId)) ? eval('$removed = array_splice($array'.((count($chapterParts)) ? '['.implode("]['subs'][",$chapterParts)."]['subs']" : '').",$lastId,1); return array_shift(\$removed);") : FALSE;
    }
    

    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:

    Array
    (
        [1] => test1
        [1.1] => test2
        [1.2] => test3
        [1.2.1] => test4
        [2] => test5
    )
    

    Now, we decide we want to remove chapter 1.2 and all it’s sub-chapters – we can do this:

    // Remove the chapter from $structure
    remove_chapter($structure, '1.2');
    // recalculate the TOC
    array_to_toc($structure, $result2);
    
    print_r($result2);
    /*
      Outputs:
      Array
      (
          [1] => test1
          [1.1] => test2
          [2] => test5
      )
    */
    

    Now lets say we want to add a chapter called test6 as chapter 1.1, and test2 will be re-indexed to 1.2 – we’ll be working with the result of the above example for this one:

    // Add the new chapter to $structure
    add_chapter($structure, '1.1', array('name'=>'test6'));
    // recalculate the TOC
    array_to_toc($structure, $result3);
    
    print_r($result3);
    /*
      Outputs:
      Array
      (
          [1] => test1
          [1.1] => test6
          [1.2] => test2
          [2] => test5
      )
    */
    

    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 $structure to demonstrate this – we’ll move chapter 1.2, so that it is now chapter 3:

    /*
      A quick reminder of what we are starting with:
      Array
      (
          [1] => test1
          [1.1] => test2
          [1.2] => test3
          [1.2.1] => test4
          [2] => test5
      )
    */
    
    // Remove the chapter from $structure - this time, we'll catch the items we remove in a variable
    $removed = remove_chapter($structure, '1.2');
    // Add it again, only this time as chapter 3
    add_chapter($structure, '3', $removed);
    
    // recalculate the TOC
    array_to_toc($structure, $result4);
    
    print_r($result4);
    /*
      Outputs:
      Array
      (
          [1] => test1
          [1.1] => test2
          [2] => test5
          [3] => test3
          [3.1] => test4
      )
    */
    

    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 $structure array 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 add 1.2.1 when 1.2 hasn’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 boolean FALSE on 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…

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have just tried to save a simple *.rtf file with some websites and
I have a jquery bug and I've been looking for hours now, I can't
I have a bunch of posts stored in text files formatted in yaml/textile (from
I have some data like this: 1 2 3 4 5 9 2 6
link Im having trouble converting the html entites into html characters, (&# 8217;) i
For some reason, after submitting a string like this Jack’s Spindle from a text
Basically, what I'm trying to create is a page of div tags, each has
I'm new to using the Perl treebuilder module for HTML parsing and can't figure
I've got a string that has curly quotes in it. I'd like to replace
this is what i have right now Drawing an RSS feed into the php,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.