mister5317 Posted February 6, 2009 Share Posted February 6, 2009 I have a string that I need converted to a nested array. See code below: // Input string $string = 'Paths.Images.Icons'; /* Need the following back: Array ( [Paths] => Array ( [images] => Array ( [icons] => Array ( ) ) ) ) */ I need a function that will parse the input string and generate a nested array based on the periods in the input string. Can someone help me create a function to do this? Thanks! Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/ Share on other sites More sharing options...
flyhoney Posted February 6, 2009 Share Posted February 6, 2009 Try this: <?php str_to_nested_array($array, 'Paths.Images.Icons'); function str_to_nested_array(&$array, $string) { function foo(&$array, $parts) { if (is_array($parts) and !empty($parts)) { $index = array_shift($parts); $array[$index] = array(); foo($array[$index] , $parts); } } foo($array, explode('.', $string)); } print_r($array); ?> Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756327 Share on other sites More sharing options...
mister5317 Posted February 6, 2009 Author Share Posted February 6, 2009 That is perfect! Can you please explain the code a little bit? I have never used a function within a function like this... Thanks again! Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756334 Share on other sites More sharing options...
mister5317 Posted February 6, 2009 Author Share Posted February 6, 2009 Sorry, one more question, is it possible to call the function with the only argument being the input string? <?php $array = str_to_nested_array('Paths.Images.Icons'); ?> Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756340 Share on other sites More sharing options...
flyhoney Posted February 6, 2009 Share Posted February 6, 2009 Yeah its kind of complicated. Here is a breakdown with comments: <?php // $array is passed by reference so that any changes made to $array // inside this function will apply to $array outside of the function function str_to_nested_array(&$array, $string) { // This is a recursive function, that means it is a function that calls itsself. // Again, $array is passed by reference so any changes made to it within foo() // will apply to $array outside of foo(). function foo(&$array, $parts) { // Make sure that the $parts array is not empty if (is_array($parts) and !empty($parts)) { // remove the first element from the $parts array $index = array_shift($parts); // create an array using $index $array[$index] = array(); // call foo again, but now $array is the nested array we just created foo($array[$index] , $parts); } } // start the process of creating the nested array foo($array, explode('.', $string)); } ?> Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756344 Share on other sites More sharing options...
flyhoney Posted February 6, 2009 Share Posted February 6, 2009 Yeah <?php $array = str_to_nested_array('Paths.Images.Icons'); print_r($array); function str_to_nested_array($string) { function foo(&$array, $parts) { if (is_array($parts) and !empty($parts)) { $index = array_shift($parts); $array[$index] = array(); foo($array[$index] , $parts); } } $array = array(); foo($array, explode('.', $string)); return $array; } ?> Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756348 Share on other sites More sharing options...
.josh Posted February 6, 2009 Share Posted February 6, 2009 I like living dangerously.... $string = 'Paths.Images.Icons.X'; $nodes = explode('.',$string); $c = count($nodes) + 1; $eval = '$structure = array(\'' . implode("' => array('", $nodes) . "' => array(" . str_repeat(")", $c) . ";"; eval($eval); echo "<pre>"; print_r($structure); Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756356 Share on other sites More sharing options...
flyhoney Posted February 6, 2009 Share Posted February 6, 2009 I like living dangerously.... $string = 'Paths.Images.Icons.X'; $nodes = explode('.',$string); $c = count($nodes) + 1; $eval = '$structure = array(\'' . implode("' => array('", $nodes) . "' => array(" . str_repeat(")", $c) . ";"; eval($eval); echo "<pre>"; print_r($structure); gross. Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756358 Share on other sites More sharing options...
.josh Posted February 6, 2009 Share Posted February 6, 2009 Don't be jealous Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756359 Share on other sites More sharing options...
printf Posted February 6, 2009 Share Posted February 6, 2009 It's no worse than using STACK overflow dangerous recursion! Me likes eval(); Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756360 Share on other sites More sharing options...
flyhoney Posted February 6, 2009 Share Posted February 6, 2009 I may be jealous, but you should be ashamed. Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756361 Share on other sites More sharing options...
flyhoney Posted February 6, 2009 Share Posted February 6, 2009 Blarg, you're faster. flyhoney: 3.6954879760742E-5 CV: 3.0040740966797E-5 but still terrible Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756368 Share on other sites More sharing options...
corbin Posted February 6, 2009 Share Posted February 6, 2009 flyhoney, are you sure you should be declaring that function in a function? What if he calls the parent function twice? Anyway, wouldn't: $e = explode('.', $str); $a = array(); $parent =& $a; foreach($e as $v) { $parent[$v] = array(); $parent =& $parent[$v]; } work? Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756381 Share on other sites More sharing options...
flyhoney Posted February 6, 2009 Share Posted February 6, 2009 Wow, I had no clue that it would throw an error. Good game to me. Yeah your solution is nice. I wasn't even aware of the =& operator! **EDIT** I am an idiot. Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756385 Share on other sites More sharing options...
corbin Posted February 6, 2009 Share Posted February 6, 2009 If we're gonna compare speeds: corbin: 1.2086191177368 cv: 3.4495089054108 flyhoney: 3.5196778774261 Hehehhe ;p. Yours could be further optimized though. Over 100,000 calls that I had it make, an extra function call can become expensive. Hrmmm.... And yeah, defining a function anywhere twice will throw a fatal error. Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756387 Share on other sites More sharing options...
flyhoney Posted February 6, 2009 Share Posted February 6, 2009 And yeah, defining a function anywhere twice will throw a fatal error. I guess I assumed that since it was within the scope of the other function it would live and die as the parent function was called. Not the case! So, poor fella that start this thread: <?php function str_to_nested_array($string) { $e = explode('.', $string); $a = array(); $parent =& $a; foreach($e as $v) { $parent[$v] = array(); $parent =& $parent[$v]; } return $a; } $array = str_to_nested_array('Paths.Images.Icons.X'); print_r($array); ?> Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756391 Share on other sites More sharing options...
.josh Posted February 6, 2009 Share Posted February 6, 2009 Okay I cleaned mine up a bit. How does this compare? $string = "Paths.Images.Icons"; $nodes = explode('.',$string); $eval = '$structure[' . implode('][', $nodes) . '] = array();'; eval($eval); Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756401 Share on other sites More sharing options...
.josh Posted February 6, 2009 Share Posted February 6, 2009 Okay corbin, you said 100k runs, right? Looks like my cleaned up version averages at 1.95s. Lot faster than before, but yours still wins :\ Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756409 Share on other sites More sharing options...
flyhoney Posted February 6, 2009 Share Posted February 6, 2009 corbin: 2.1934509277344E-5 CV: 2.598762512207E-5 I also had to edit your code: $eval = '$structure[\'' . implode('\'][\'', $nodes) . '\'] = array();'; to not throw errors Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756410 Share on other sites More sharing options...
.josh Posted February 6, 2009 Share Posted February 6, 2009 Yeah I knew that would happen. Final code: function strToNestedArray($string) { return eval('$structure[\'' . implode('\'][\'', explode('.',$string)) . '\'] = array();'); } corbin's is a little faster but come on, like 0.4s over 100k times is not even worth mentioning, and let's face it, mine is sexier. Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756416 Share on other sites More sharing options...
corbin Posted February 6, 2009 Share Posted February 6, 2009 flyhoney, it looks like you're testing things with 1 iteration.... I usually do at least a couple thousand since it can be misleading to only do it once. Anyway, CV, I don't know what beastly hardware you're running, but I get this: corbin: 1.226273059845 cv: 2.9218299388885 With your new function. Perhaps you're using a shorter string and it's not hardware. Eitherway, try BM'ing both of ours on your machine. Edit: CV, I'm quite sure your newest function will return NULL. Regardless: corbin: 1.215723991394 cv: 2.9700248241425 And yes, yours is much sexier. Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756417 Share on other sites More sharing options...
.josh Posted February 6, 2009 Share Posted February 6, 2009 hmmm...apparently it's faster for me to separate the calls.... you did kick my ass in the speed test when I reduced it: <?php // corbin's function function str_to_nested_array($string) { $e = explode('.', $string); $a = array(); $parent =& $a; foreach($e as $v) { $parent[$v] = array(); $parent =& $parent[$v]; } return $a; } // crayon's function function strToNestedArray($string) { eval('$structure[\'' . implode('\'][\'', explode('.',$string)) . '\'] = array();'); return $structure; } $str = "path.to.something"; echo "100k call * 10 benchmarking: <br/><br/>"; echo "Crayon Test<br/>"; for ($y = 0; $y < 10; $y++) { $start = microtime(true); for ($x = 0; $x < 100000; $x++) { $structure = strToNestedArray($str); } $time = microtime(true) - $start; echo $time . "<br/>"; } echo "<br/>Corbin Test<br/>"; for ($y = 0; $y < 10; $y++) { $start = microtime(true); for ($x = 0; $x < 100000; $x++) { $array = str_to_nested_array($str); } $time = microtime(true) - $start; echo $time . "<br/>"; } 100k call * 10 benchmarking: Crayon Test 1.42691397667 1.41678309441 1.42388701439 1.42499303818 1.43931484222 1.41837310791 1.42116189003 1.4214861393 1.41087889671 1.4306139946 Corbin Test 0.469434022903 0.469136953354 0.466317176819 0.471101999283 0.463952064514 0.470424890518 0.477626800537 0.474759101868 0.469851016998 0.471065044403 Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756428 Share on other sites More sharing options...
corbin Posted February 7, 2009 Share Posted February 7, 2009 I'm jealous of your processor (well, I used a decent length string; perhaps you used very short) . But like you said, in the real world, this function would probably be used 1-100 times on a page, meaning the time difference would be so small it wouldn't matter. 0.000014 - .0000047 = 0.0000093 per call. >.< And your solution is definitely sexier ;p. To be honest though, I would think your solution would be slower than it is. Eval and string functions.... Weird. Edit: Just realized why the string and eval don't matter much (especially the string functions).... Our data sets were small. Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756434 Share on other sites More sharing options...
.josh Posted February 7, 2009 Share Posted February 7, 2009 10 'layers' String Used: something.something.something.something.something.something.something.something.something.something 100k call * 10 benchmarking: Crayon Test 2.87430691719 2.93059802055 2.80796098709 2.83842396736 2.80413508415 2.80233502388 2.81222605705 2.80466985703 2.81069684029 2.79373407364 Corbin Test 1.18330597878 1.18677306175 1.21304512024 1.18618011475 1.18019294739 1.19304704666 1.18475985527 1.19489097595 1.20416808128 1.19843006134 100 'layers' String Used: something.something.something.something.something.something.something.something.something.something. something.something.something.something.something.something.something.something.something.something. something.something.something.something.something.something.something.something.something.something. something.something.something.something.something.something.something.something.something.something. something.something.something.something.something.something.something.something.something.something. something.something.something.something.something.something.something.something.something.something. something.something.something.something.something.something.something.something.something.something. something.something.something.something.something.something.something.something.something.something. something.something.something.something.something.something.something.something.something.something. something.something.something.something.something.something.something.something.something.something 100k call * 10 benchmarking: Crayon Test 20.3001179695 17.857063055 17.776542902 17.6992988586 17.8040530682 17.7113671303 17.9984920025 18.9144699574 17.6936171055 17.8100349903 Corbin Test 9.2130241394 9.54194021225 9.23869395256 9.26948809624 9.1253631115 9.40434908867 9.11741280556 9.14707803726 9.14307904243 9.22559309006 Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756445 Share on other sites More sharing options...
.josh Posted February 7, 2009 Share Posted February 7, 2009 btw this is my host's server info: http://74.54.71.140/~netadmin/ Quote Link to comment https://forums.phpfreaks.com/topic/144139-string-to-array/#findComment-756450 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.