Jump to content

String to Array


mister5317

Recommended Posts

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!

 

 

Link to comment
Share on other sites

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);
?>

Link to comment
Share on other sites

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));
}
?>

Link to comment
Share on other sites

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;
}
?>

Link to comment
Share on other sites

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. :P

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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);
?>

Link to comment
Share on other sites

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.

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.