Skip to content

Instantly share code, notes, and snippets.

@Dinir
Last active October 6, 2017 06:45
Show Gist options
  • Save Dinir/df85274c220edd38d1cbe22604d965d5 to your computer and use it in GitHub Desktop.
Save Dinir/df85274c220edd38d1cbe22604d965d5 to your computer and use it in GitHub Desktop.
Turn an indented text list to a multi-dimensional array.
<?php
$tree_text = function(string $text): array {
$lines = explode(PHP_EOL, $text);
$levels = array_map(function($line){
$level = 0;
while(substr($line, $level, 1) == "\t") {
$level++;
}
return $level;
}, $lines);
array_walk($lines, function(&$line, $key, $level) {
$line = trim(substr($line, $level[$key]));
}, $levels);
reset($levels);
reset($lines);
$curr_level = 0;
$attempt = 0;
$generate_tree = function() use (
&$generate_tree, &$lines, &$levels, &$curr_level, &$attempt
) {
$tree = [];
while(key($lines) !== null && $attempt <= 1000) {
$attempt++;
switch($curr_level <=> current($levels)) {
case 0:
$tree[current($lines)] = [];
next($lines);
next($levels);
break;
case -1:
$curr_level++;
end($tree);
$tree[key($tree)] = $generate_tree();
break;
case 1:
$curr_level--;
break 2;
}
}
if(array_filter($tree))
return $tree;
else
return array_keys($tree);
};
return $generate_tree();
};
@Dinir
Copy link
Author

Dinir commented Sep 19, 2017

Example of expected input and output:

$text = <<<TEXT
Henlo
	lizer
helllo
	you
	STINKY
		LIZARD
go
	eat
		a fly
		ugly
TEXT;
array(3) {
  ["Henlo"]=>
  array(1) {
    [0]=>
    string(5) "lizer"
  }
  ["helllo"]=>
  array(2) {
    ["you"]=>
    array(0) {
    }
    ["STINKY"]=>
    array(1) {
      [0]=>
      string(6) "LIZARD"
    }
  }
  ["go"]=>
  array(1) {
    ["eat"]=>
    array(2) {
      [0]=>
      string(5) "a fly"
      [1]=>
      string(4) "ugly"
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment