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.
source to share
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));
source to share
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.
source to share
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.
source to share
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.
source to share