Re: [PHP] Converting string representation of a directory to multi-dimensional array
Richard Lynch wrote: On Mon, February 5, 2007 12:27 pm, Matt Carlson wrote: Over the weekend, I was tasked with taking a string representation of a directory ('\Interface\Addons\some dir\some file'), which can vary in length (no set number of depths) to a multi-dimensional array (i.e. array('Interface' = array('Addons' = array('some dir' = somefile)));). We came up with a very ugly hack to do it, but I'm curious if anyone can help us wrap our head around a better solution, without using eval (which we were able to find that solution quickly, but do not want to use eval). Our situation is a little unique in the fact that these files don't actually exist on a filesystem, so it makes it a bit more tough to actually create this array. Thanks for any help you can give in cleaning this up somewhat. Here is the function we currently use: ?php $array = array(); addToList('\interface\addons\clearfont\clearfont.toc2', $array); addToList('\interface\addons\clearfont\clearfont.toc3', $array); addToList('\interface\addons\clearfont\clearfont.toc4', $array); addToList('\interface\addons\clearfont\clearfont.toc5', $array); addToList('\interface\addons\clearfont\subdir\something.toc', $array); function addToList($path){ $parts = explode('\\', $path); $result = array(); $parts = array_reverse($parts); foreach($parts as $part){ //something with array_splice here... $result = array_splice(array($result), $part); //??? array_splice won't cut it as it only splices at 1 level, unless I misunderstood the OP is looking to dynamically build a multilevel array - which means either using recursion or 'reference based array digging' (as I like to call it ;-) there may also be some kind of solution based on ArrayArrayArrayIteratorIteratorRecursiveArrayIteratorIteratorRecursiveIterator but personally I don't grok those exotic forms of SPL interface well enough to tell you. } } -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Converting string representation of a directory to multi-dimensional array
# [EMAIL PROTECTED] / 2007-02-06 12:45:22 +0100: there may also be some kind of solution based on ArrayArrayArrayIteratorIteratorRecursiveArrayIteratorIteratorRecursiveIterator but personally I don't grok those exotic forms of SPL interface well enough to tell you. I had wanted to post something when the thread started, but gave up, because I quickly ran into ambiguities. What should the conversion do when given a basename, e. g. addToList(file.txt, ...)? Anyway, here's an implementation, and a few Testilence tests. The code doesn't provide for iteration since, AFAICT, the OP is looking for a map, not an iterable collection. ?php class pata implements ArrayAccess { function __construct($path, $sep = '/') { $this-sep = $sep; $path = trim($path, $sep); if ($this-isBasename($path)) { throw new InvalidArgumentException; } list($key, $rest) = $this-split($path); $this-key = $key; if ($this-isBasename($rest)) { $this-data = $rest; } else { $this-data = new self($rest, $sep); } } function __toString() { return $this-key . $this-sep . $this-data; } function offsetExists($key) { return $this-key === $key; } function offsetGet($key) { return $this-data; } function offsetUnset($key) { throw new LogicException; } function offsetSet($key, $value) { throw new LogicException; } private function isBasename($path) { return (false === strpos($path, $this-sep)); } private function split($path) { $sp = $this-strpos($path, $this-sep); $key = substr($path, 0, $sp); $rest = trim(substr($path, $sp), $this-sep); return array($key, $rest); } private function strpos($haystack, $needle) { $rv = strpos($haystack, $needle); return (false === $rv) ? strlen($haystack) : $rv; } private $key, $data = array(); } class pata_SingleSegmentTest extends Tence_TestCase { function testThrowsOnBaseName() { $this-willThrow('InvalidArgumentException'); new pata('foo'); } } abstract class pata_MultipleSegmentTest extends Tence_TestCase { abstract protected /* string */ function separator(); function setUp() { $this-garbage = 'garbage'; $this-key = 'foo'; $segments = array('bar', 'baz'); $sep = $this-separator(); $this-path = implode($sep, $segments); $this-pata = new pata($this-key . $sep . $this-path, $sep); } function testIssetWithPathAsKeySucceeds() { return $this-assertTrue(isset($this-pata[$this-key])); } function testIssetWithWrongKeyFails() { return $this-assertFalse(isset($this-pata[$this-garbage])); } function testGetWithPathAsKey() { return $this-assertEquals($this-path, $this-strval($this-pata[$this-key])); } private function strval($v) { if (is_object($v)) { return $v-__toString(); } else { return strval($v); } } } class pata_WinTest extends pata_MultipleSegmentTest { function separator() { return '\\'; } } class pata_POSIXTest extends pata_MultipleSegmentTest { function separator() { return '/'; } } class pata_tests extends Tence_TestSuite { function __construct() { $this -add(new pata_SingleSegmentTest) -add(new pata_WinTest) -add(new pata_POSIXTest) ; } } ? -- How many Vietnam vets does it take to screw in a light bulb? You don't know, man. You don't KNOW. Cause you weren't THERE. http://bash.org/?255991 -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Converting string representation of a directory to multi-dimensional array
It will never receive a base name due to the way the data is structured before being passed into the function. I appreciate everyone's input on this. It's been tough for us to develop what we did (since it's such an odd case), and it's good to see other possible methods to do this in a better manor. - Original Message From: Roman Neuhauser [EMAIL PROTECTED] To: Jochem Maas [EMAIL PROTECTED] Cc: php-general@lists.php.net Sent: Tuesday, February 6, 2007 9:03:35 AM Subject: Re: [PHP] Converting string representation of a directory to multi-dimensional array I had wanted to post something when the thread started, but gave up, because I quickly ran into ambiguities. What should the conversion do when given a basename, e. g. addToList(file.txt, ...)? -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP] Converting string representation of a directory to multi-dimensional array
Over the weekend, I was tasked with taking a string representation of a directory ('\Interface\Addons\some dir\some file'), which can vary in length (no set number of depths) to a multi-dimensional array (i.e. array('Interface' = array('Addons' = array('some dir' = somefile)));). We came up with a very ugly hack to do it, but I'm curious if anyone can help us wrap our head around a better solution, without using eval (which we were able to find that solution quickly, but do not want to use eval). Our situation is a little unique in the fact that these files don't actually exist on a filesystem, so it makes it a bit more tough to actually create this array. Thanks for any help you can give in cleaning this up somewhat. Here is the function we currently use: ?php $array = array(); addToList('\interface\addons\clearfont\clearfont.toc2', $array); addToList('\interface\addons\clearfont\clearfont.toc3', $array); addToList('\interface\addons\clearfont\clearfont.toc4', $array); addToList('\interface\addons\clearfont\clearfont.toc5', $array); addToList('\interface\addons\clearfont\subdir\something.toc', $array); function addToList($str, $array) { $things = explode('\\', $str); if($things['0'] == '') { array_shift($things); } addToArray($things, $array); } function addToArray($things, $array) { $count = count($things); switch ($count) { case '1': $array[$things['0']] = $array(); break; case '2': $array[$things['0']][$things['1']] = $things['1']; break; case '3': $array[$things['0']][$things['1']][$things['2']] = $things['2']; break; case '4': $array[$things['0']][$things['1']][$things['2']][$things['3']] = $things['3']; break; previous code repeated down to 10 default: break; } } print_r($array); ? -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Converting string representation of a directory to multi-dimensional array
Matt Carlson wrote: Over the weekend, I was tasked with taking a string representation of a directory ('\Interface\Addons\some dir\some file'), which can vary in length (no set number of depths) to a multi-dimensional array (i.e. array('Interface' = array('Addons' = array('some dir' = somefile)));). We came up with a very ugly hack to do it, but I'm curious if anyone can help us wrap our head around a better solution, without using eval (which we were able to find that solution quickly, but do not want to use eval). Our situation is a little unique in the fact that these files don't actually exist on a filesystem, so it makes it a bit more tough to actually create this array. Thanks for any help you can give in cleaning this up somewhat. Here is the function we currently use: based on an answer to an old post ... below shows how to uses references to walk 'into' an array and set/create multilevel elements - given a bit of thought you should be able to figure out how to apply the concept to your own problem: ?php $ref = null; $keys = array(six,five,four,three,two,one); $val = string value; // the node value $arr = array(); // generated array $ref = $arr; while ($key = array_pop($keys)) { $ref[$key] = array(); $ref = $ref[$key]; } $ref = $val; var_dump($arr); -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Converting string representation of a directory to multi-dimensional array
On Mon, February 5, 2007 12:27 pm, Matt Carlson wrote: Over the weekend, I was tasked with taking a string representation of a directory ('\Interface\Addons\some dir\some file'), which can vary in length (no set number of depths) to a multi-dimensional array (i.e. array('Interface' = array('Addons' = array('some dir' = somefile)));). We came up with a very ugly hack to do it, but I'm curious if anyone can help us wrap our head around a better solution, without using eval (which we were able to find that solution quickly, but do not want to use eval). Our situation is a little unique in the fact that these files don't actually exist on a filesystem, so it makes it a bit more tough to actually create this array. Thanks for any help you can give in cleaning this up somewhat. Here is the function we currently use: ?php $array = array(); addToList('\interface\addons\clearfont\clearfont.toc2', $array); addToList('\interface\addons\clearfont\clearfont.toc3', $array); addToList('\interface\addons\clearfont\clearfont.toc4', $array); addToList('\interface\addons\clearfont\clearfont.toc5', $array); addToList('\interface\addons\clearfont\subdir\something.toc', $array); function addToList($path){ $parts = explode('\\', $path); $result = array(); $parts = array_reverse($parts); foreach($parts as $part){ //something with array_splice here... $result = array_splice(array($result), $part); //??? } } -- Some people have a gift link here. Know what I want? I want you to buy a CD from some starving artist. http://cdbaby.com/browse/from/lynch Yeah, I get a buck. So? -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php