1

I am trying to get it so that the output that is as follows (currently):

┌── Level 0 Child 1
└── Level 0 Child 2
|   ├── Level 1 Child 1
|   |   └── Level 1 Child 1 Grandchild 1
|   └── Level 1 Child 2
|   |   ├── Level 1 Child 2 Grandchild 1
|   |   |   ├── Level 1 Child 2 Grandchild 1 Great-grandchild 1
|   |   |   ├── Level 1 Child 2 Grandchild 1 Great-grandchild 2
|   |   |   └── Level 1 Child 2 Grandchild 1 Great-grandchild 3
|   |   └── Level 1 Child 2 Grandchild 2
|   |   |   └── Level 1 Child 2 Grandchild 2 Great-grandchild 1

to be correct.

Obviously, the actual outcome i want is where not every square has the vertical lines, if that node has already reached its end of the line └──.

This is my current code:

function makeList(array $array, $level = 0, $very_first_item = true)
{
    $output = "\n";
    $count = 0;
    foreach ($array as $key => $subArray) {
        if($count == count($array) - 1) {
            $prefix = str_repeat('|   ', $level) . '└── ';
        } elseif($very_first_item === true) {
            $prefix =  str_repeat('|   ', $level) . '┌── ';
        } else {
            $prefix = str_repeat('|   ', $level) . '├── ';
        }
        $very_first_item = false;
        $output .= $prefix . $key . makeList($subArray, $level + 1, $very_first_item);
        $count++;
    }

    return $output;
}

This is the array to be passed in:

array(
    'Level 0 Child 1' =>
        array(),
    'Level 0 Child 2' =>
        array(
            'Level 1 Child 1' =>
                array(
                    'Level 1 Child 1 Grandchild 1' =>
                        array(),
                ),
            'Level 1 Child 2' =>
                array(
                    'Level 1 Child 2 Grandchild 1' =>
                        array(
                            'Level 1 Child 2 Grandchild 1 Great-grandchild 1' =>
                                array(),
                            'Level 1 Child 2 Grandchild 1 Great-grandchild 2' =>
                                array(),
                            'Level 1 Child 2 Grandchild 1 Great-grandchild 3' =>
                                array(),
                        ),
                    'Level 1 Child 2 Grandchild 2' =>
                        array(
                            'Level 1 Child 2 Grandchild 2 Great-grandchild 1' =>
                                array(),
                        ),
                ),
        ),
);
Bowersbros
  • 3,438
  • 2
  • 18
  • 24

1 Answers1

0

Please check if this code can help you.

I have changed your makeList function, also added another function with the name of array_depth which calculates the depth of your array using this post and also added another node to the end of your array to check if the code is working properly. so, here's the code:

$myArr = array(
    'Level 0 Child 1' => array(),
    'Level 0 Child 2' => array(
        'Level 1 Child 1' => array(
            'Level 1 Child 1 Grandchild 1' => array(),
        ),
        'Level 1 Child 2' => array(
            'Level 1 Child 2 Grandchild 1' =>   array(
                'Level 1 Child 2 Grandchild 1 Great-grandchild 1' => array(),
                'Level 1 Child 2 Grandchild 1 Great-grandchild 2' => array(),
                'Level 1 Child 2 Grandchild 1 Great-grandchild 3' => array(),
            ),
            'Level 1 Child 2 Grandchild 2' => array(
                'Level 1 Child 2 Grandchild 2 Great-grandchild 1' => array(),
            ),
        ),
    ),
    'Level 0 Child 3' => array(
        'Level 1 Child 1' => array(
            'Level 1 Child 1 Grandchild 1' => array(),
        ),
    )
);

function array_depth(array $array){
    $max_depth = 1;

    foreach ($array as $value){
        if (is_array($value)){
            $depth = array_depth($value) + 1;

            if ($depth > $max_depth){
                $max_depth = $depth;
            }
        }
    }

    return $max_depth;
}


function makeList(array $array, $level = 0, $very_first_item = true)
{
    global $arrLines;
    $output = "\n";
    $count = 0;
    foreach ($array as $key => $subArray) {
        if($count == count($array) - 1) {
            $prefix = '└── ';
            $arrLines[$level + 1] = '    ';
        } elseif($very_first_item === true) {
            $prefix =  '┌── ';
            $arrLines[$level + 1] = '|   ';
        } else {
            $prefix = '├── ';
            $arrLines[$level + 1] = '|   ';
        }
        $very_first_item = false;
        for($iCnt = 1; $iCnt <= $level; $iCnt++)
            $output .=  $arrLines[$iCnt];
        $output .= $prefix . $key . makeList($subArray, $level + 1, $very_first_item);
        $count++;
    }

    return $output;
}

$arrLines = array(array_depth($myArr));
echo '<pre>'.makeList($myArr).'</pre>';
Community
  • 1
  • 1
EhsanT
  • 2,077
  • 3
  • 27
  • 31
  • That looks fantastic. Thank you. :) What name or github link do you have so I can credit you for improving the code? – Bowersbros Apr 11 '15 at 23:31
  • Thanks man, it's most generous of you. I do not have github account and the real work was done by "Jeremy Ruten" which had developed the `array_depth` function. have fun coding. :) – EhsanT Apr 12 '15 at 00:11
  • Please can you link to the array_depth so i can attribute it properly? thanks :) – Bowersbros Apr 12 '15 at 01:35