Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to parse some data and just cant seem to figure it out myself. I have the array data of something like this, where the string should be turned into a path to the array index. See below:

{
    'one/two':3,
    'one/four/0':5
    'one/four/1':6,
    'one/four/2':7,
    'eight/nine/ten':11
}

and am trying to turn it into a json array like so

{
    'one': { 
        'two': 3,
        'four': [5, 6, 7]
    },
    'eight': {
        'nine': {
            'ten':11
         }
    }
}

I have tried using recursion and got the general idea but i cant seem to work out getting the array indexes to line up right. Here is what I have so far:

public function reverse() {

$reversedValues= array();
foreach ( $this->sorted as $key=>$value ) {

    array_push( $this->reversedPaths ,$key  );
    array_push( $reversedValues , $value ); 
    //print_r($this->reversed);
    echo "<br />";

}
$this->reversed = $this->stringToArray($this->reversedPaths[0] , $reversedValues);
var_dump($this->reversed);
return  json_encode($this->reversed , false);
}

private function stringToArray($path , $values , $count = 0) {

$separator = '/';

$pos = strpos($path, $separator);

if ($pos === false) {
    //check for numbers so we know to add those to an json object
    if (is_numeric($path)) {
        //add it to the parent array of values...
    } 

    $reversed = array(
        $path => $values[$count],
    );

    return $reversed;
}

$key = substr($path, 0, $pos);
$path = substr($path, $pos + 1);


$reversed[$key] = $this->stringToArray($path  ,  $values , $count);
$count++;
//read in next path string
if (array_key_exists( $count ,$this->reversedPaths)) {

     $currentpos = strpos($this->reversedPaths[$count],  $path.$separator);
     $currentPath = substr($this->reversedPaths[$count], $currentpos );
     $nextpos = strpos($currentPath,  $separator);
     if ($nextpos === false) {

     } else {
         $nextPath = substr($currentPath, $nextpos + 1);
         $nextKey = substr($nextPath, 0, $nextpos);
         echo $nextKey;
         echo $nextPath;
        // echo $nextKey;
        //if this key equals first value of next path dont return but process recurssion again on it

        if ($nextKey !== false  ) {

            $reversed[$key][$nextKey] = $this->stringToArray($nextPath  ,  $values , $count);
        }
    }
} else {

}

return $reversed;



}

I was trying to read in the next path data to check if it is within the same array index but i just couldn't get it working. I know i am over complicating it but it doesn't seem like there is any easy way to accomplish this...

share|improve this question

1 Answer 1

up vote 2 down vote accepted

I had a crack at this. Based on the details you provided, it looks like you are trying to create a tree, like a directory structure: each / delimited string in the key represents a 'depth'. The solution I found was to create a multidimensional array for each element, parsing the current key into levels and recursively merge/replace the result into a master 'tree' array. This is what I have:

// original JSON string

$json = '{
    "one/two": 3,
    "one/four/0": 5,
    "one/four/1": 6,
    "one/four/2": 7,
    "eight/nine/ten": 11
}';

// convert to a PHP multidimensional array

$array = json_decode($json, true);

// init an array to hold the final result

$tree = [];

// iterate over the array of values
// explode the key into an array 'path' tokens
// pop each off and build a multidimensional array
// finally 'merge' the result into the result array

foreach ($array as $path => $value) {
    $tokens = explode('/', $path);
    while (null !== ($key = array_pop($tokens))) {
        $current = [$key => $value];
        $value = $current;
    }
    $tree = array_replace_recursive($tree, $value);
}

// show the result!

print_r(json_encode($tree, JSON_PRETTY_PRINT));

Yields:

{
    'one': {
        'two': 3,
        'four': [5, 6, 7]
    },
    'eight': {
        'nine': {
            'ten':11
         }
    }
}

Hope this helps :)

share|improve this answer
1  
Working example: eval.in/131036 –  Darragh Apr 2 at 23:26
    
Thank you for your effort. This does indeed solve the problem at hand! thanks again –  Pengume Apr 2 at 23:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.