Indented list to multidimensional array

I was surprised I didn't find an answer to this on SO (or elsewhere on the internet, for that matter). This is for nested indentation, which I want to convert to a multidimensional array according to the indentation level.

As an example, here are some examples of input:

Home
Products
    Product 1
        Product 1 Images
    Product 2
        Product 2 Images
    Where to Buy
About Us
    Meet the Team
    Careers
Contact Us

      

Ideally, I would like to pass this to some (recursive?) Function and get the following output:

array(
    'Home' => array(),
    'Products' => array(
        'Product 1' => array(
            'Product 1 Images' => array(),
        ),
        'Product 2' => array(
            'Product 2 Images' => array(),
        ),
        'Where to Buy' => array(),
    ),
    'About Us' => array(
        'Meet the Team' => array(),
        'Careers' => array(),
    ),
    'Contact Us' => array(),
);

      

I am confused by the logic required to accomplish such a task, so any help would be appreciated.

+2


source to share


4 answers


As it is still unclear if you are trying to read any given structure (html-dom) or from a given line as plain text, I assumed that this is the line you are trying to parse. If so, try:

<?php
$list =
'Home
Products
    Product 1
        Product 1 Images
    Product 2
        Product 2 Images
    Where to Buy
About Us
    Meet the Team
    Careers
Contact Us';

function helper($list, $indentation = '    ') {
  $result = array();
  $path = array();

  foreach (explode("\n", $list) as $line) {
    // get depth and label
    $depth = 0;
    while (substr($line, 0, strlen($indentation)) === $indentation) {
      $depth += 1;
      $line = substr($line, strlen($indentation));
    }

    // truncate path if needed
    while ($depth < sizeof($path)) {
      array_pop($path);
    }

    // keep label (at depth)
    $path[$depth] = $line;

    // traverse path and add label to result
    $parent =& $result;
    foreach ($path as $depth => $key) {
      if (!isset($parent[$key])) {
        $parent[$line] = array();
        break;
      }

      $parent =& $parent[$key];
    }
  }

  // return
  return $result;
}

print_r(helper($list));

      



Demo: http://codepad.org/zgfHvkBV

+9


source


I won't write a recursive function, but to point you in a useful direction, take a look at PHP's substr_count . Based on this, you can count the number of tabs before each line and compare them to the number of tabs in the previous line to find out if it is child, native, etc.



0


source


Am I the only one who has a beautiful look when seeing a pattern?

The input array is pretty much the same! With lines ending in only three possible ways: opening, whole, or closing parentheses.

$L = 4;//estimate depth level

function tabbed_text_to_array ($raw, $L) {

        $raw = preg_replace("/^(\\t*)([^\\t\\n]*)\\n?/m" ,  "\t$1'$2' => array(\n" , $raw );

    for( ; $L > 0 ; $L-- ) {

        for( $i=0; $i<3 ;$i++ ) {
            $preL = $L-1;
            $s = array( "^(\\t{{$L}})([^\\t\\),]*)(?=\\n\\t{{$L}}')", "^(\\t{{$L}})([^\\t\\),]*)(?=\\n(\\t{0,{$preL}})')", "^(\\t{{$L}})(\\),)(?=\\n(\\t{{$preL}})[^\t])" );
            $r = array(    "$1$2),"   ,     "$1$2)\n" . str_repeat("\t",$preL) . "),"    ,    "$1),\n$3),"    );
            $raw = preg_replace( "/$s[$i]/m" , $r[$i], $raw );
        }
    }
    return "array(\n". $raw. ")\n);";   

}

      

This function generates a literal array string. Then you just eval () this. This is not as bad as it sounds. The double backslash makes it harder to read, but it's simple.

Similar to multiplying cells, it first adds the most common things in one pass: quotes, commas, and open parentheses, and then adds finer details in two passes. They all run once for each level you specify (you can spend code searching for the deepest level to start processing, but guesswork is enough.)

See a working demo / tool to convert text with stools to an array

Or check out the php fiddle with all the passes so you can expand on this.

0


source


PHP scripts have a class that will do what you want. You can find it here: Array for List

It takes a multidimensional array and creates HTML.

Update

The opposite was required. The best way to do this is to use the DOMDocument object and load the HTML into the object's view.

http://php.net/manual/en/domdocument.loadhtml.php

-2


source







All Articles