-1

Title isn't great, but I think I can explain better what I want to achieve like so:

Given a flat file:

MAIN 0
  Sub Heading 0
  Sub Heading 1
MAIN 1
  Sub Heading 0
    Sub Sub Heading 0
    Sub Sub Heading 1
  Sub Heading 1
  Sub Heading 2
    Sub Sub Heading 0
      Sub Sub Sub Heading 0
MAIN 2
  Sub Heading 0

How can I create a nested 'array of arrays' structure from this? A child is defined by being prepended by a TAB character from it's parent.

I am trying to do this in php, currently, and don't have much work to show. I'm stuck trying to work out the logic.

I believe the best solution will probably be some kind of recursion, and perhaps a tab_count variable and a tab_count_ceiling variable?

I started doing this in php, but honestly, I have no language preference for this. Which code can solve such a problem?

hakre
  • 193,403
  • 52
  • 435
  • 836
Kevin
  • 1,489
  • 2
  • 20
  • 30
  • 1
    You could try using a YAML parser. Are you able to alter the structure of the file to include : at each heading? – Jessica Jun 09 '13 at 23:04
  • 1
    me, I find the title rather nice – Casimir et Hippolyte Jun 09 '13 at 23:57
  • @Jessica clever hack. Yes I think I could do that, and yes that might solve the problem. I am more interested in understanding how to solve this problem. Obviously whatever YAML module I use is solving this problem. I'll consider looking at some of their code to see what they do – Kevin Jun 10 '13 at 00:34
  • What do you want to obtain: `array('MAIN 0'=>array('Sub Heading 0', 'Sub Heading 1')...)` OR `array('MAIN 0'=>array('Sub Heading 0'=>'', 'Sub Heading 1'=>'')...)` OR other? – Casimir et Hippolyte Jun 10 '13 at 01:13
  • @CasimiretHippolyte the second one would be great – Kevin Jun 10 '13 at 01:28
  • Please see [convert tab/space delimited lines into nested array](http://stackoverflow.com/q/9797261/367456) and [Indented list to multidimensional array](http://stackoverflow.com/q/8881037/367456) just to give two examples of duplicate questions. – hakre Jun 10 '13 at 07:10

1 Answers1

1

Just for fun i wrote this code.

ini_set('error_reporting', -1);
ini_set('display_errors', 1);

/**
 * Recognising level of current header and header itself by counting prefixes
 * before header
 * @param string $string
 * @param string $prefix
 * @param &int $level
 * @param &string $header
 */
function myGetLevelAndHeader($string, $prefix, &$level, &$header)
    {
    preg_match('/^((?:' . preg_quote($prefix) . ')*)(.*)$/', $string, $match);
    $header = $match[2];
    $level = strlen($match[1]) / strlen($prefix);
    }

/**
 * Adding to headers array to the desired dimension without recursion
 * @param &array $headers ere
 * @param integer $level
 * @param string $header
 */
function myAddToHeaders(array &$headers, $level, $header)
    {
    $array = &$headers;
    while ($level--)
        {
        //adding new dimension
        is_null($array) ? $array = array() : end($array);

        $last_key = key($array);
        if (!is_null($last_key) && is_array($array[$last_key]))
            $array = &$array[$last_key]; // going deeper
        else
            $array = &$array[]; // create new element and going deeper
        };
    $array[] = $header;
    }

/**
 * Simple parsing function
 * @param array $lines
 * @param string $prefix
 * @return array
 */
function myParse(array $lines, $prefix = '  ')
    {
    $headers = array();
    foreach ($lines as $line)
        {
        myGetLevelAndHeader($line, $prefix, $level, $header);
        myAddToHeaders($headers, $level, $header);
        }
    return $headers;
    }

$lines = file('file.txt');

print_r(myParse($lines, '  '));
sectus
  • 15,605
  • 5
  • 55
  • 97