Indented list to multidimensional array

前端 未结 4 682
后悔当初
后悔当初 2020-12-06 08:21

I was surprised not to find an answer to this on SO (or elsewhere on the internet for that matter). It concerns a nested indented list which I want to convert into a multidi

相关标签:
4条回答
  • 2020-12-06 09:03

    As it's still unclear if you're trying to read from some given structure (html-dom) or from the given string as plain text, I assumed it's the string you're 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

    0 讨论(0)
  • 2020-12-06 09:04

    There is a class on PHP Scripts that will do what you need. You can find it here: Array To List

    It takes a multidimensional array and creates the HTML.

    Updated

    The opposite to this was actually required. To do this, it's probably best to use a DOMDocument object and load the HTML into a object representation.

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

    0 讨论(0)
  • 2020-12-06 09:13

    Am I the only one with a beautiful mind seeing the pattern?

    The input array is almost the same thing!, with the lines ending in only 3 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 string with a literal array. Then you just eval() it. It's not as bad as it looks. The double backslashes makes the reading harder, but it's simple.

    Like cell reproduction, it first adds in one pass the most common things: the quotation marks, commas and opening parentheses, and then it adds the smaller details in two more passes. All of them run once for each level you specify (You could waste code in finding out the deepest level to start processing from, but a guess is enough.)

    See the working demo / tool to convert tab-indented text into array

    Or visit a php fiddle with all the passes, so you can expand on this.

    0 讨论(0)
  • 2020-12-06 09:19

    I'm not going to write the recursive function, but to point you in a helpful direction, take a look at PHP's substr_count function. Based on this, you could count the number of tabs in front of each line and compare it with the number of tabs in the previous line to figure out if it's a child, sibling, etc.

    0 讨论(0)
提交回复
热议问题