Ensure order in for loop involving json_decode()

58 views Asked by At

I'm using json_decode to parse JSON files. In a for loop, I attempt to capture specific cases in the JSON in which one element or another exist. I've implemented a function that seems to fit my needs, but I find that I need to use two for loops to get it to catch both of my cases.

I would rather use a single loop, if that's possible, but I'm stuck on how to get both cases caught in a single pass. Here's a mockup of what I would like the result to look like:

<?php
function extract($thisfile){
    $test = implode("", file($thisfile));
    $obj = json_decode($test, true);

    for ($i = 0; $i <= sizeof($obj['patcher']['boxes']); $i ++) {
        //this is sometimes found 2nd
        if ($obj['patcher']['boxes'][$i]['box']['name'] == "mystring1") {
        }

        //this is sometimes found 1st
        if ($obj['patcher']['boxes'][$i]['box']['name'] == "mystring2") {
        }
    }    
}
?>

Can anyone tell me how I could catch both cases outlined above within a single iteration? I clearly could not do something like

if ($obj['patcher']['boxes'][$i]['box']['name'] == "string1" && $obj['patcher']['boxes'][$i]['box']['name'] == "string2") {}

...because that condition would never be met.

2

There are 2 answers

0
jml On BEST ANSWER

I found that something like what @Jon had mentioned is probably the best way to attack this problem, for me at least:

<?php
function extract($thisfile){
    $test = implode("", file($thisfile));
    $obj = json_decode($test, true);
    $found1 = $found2 = false;

    for ($i = 0; $i <= sizeof($obj['patcher']['boxes']); $i ++) {
        //this is sometimes found 2nd
        if ($obj['patcher']['boxes'][$i]['box']['name'] == "mystring1") {
            $found1 = true;
        }

        //this is sometimes found 1st
        if ($obj['patcher']['boxes'][$i]['box']['name'] == "mystring2") {
            $found2 = true;
        }

        if ($found1 && $found2){ 
            break;
        }
    }    

}
?>
2
Aesphere On

Generally what I do when I have raw data that is in an order that isn't ideal to work with is to run a first loop pass to generate a a list of indexes for me to pass through a second time. So a quick example from your code:

<?php
function extract($thisfile){
    $test = implode("", file($thisfile));
    $obj = json_decode($test, true);

    $index_mystring2 = array(); //Your list of indexes for the second condition

    //1st loop.
    $box_name;
    for ($i = 0; $i <= sizeof($obj['patcher']['boxes']); $i ++) {
        $box_name = $obj['patcher']['boxes'][$i]['box']['name'];

        if ( $box_name == "mystring1") {
             //Do your code here for condition 1
        }

        if ($box_name == "mystring2") {
           //We push the index onto an array for a later loop.
           array_push($index_mystring2, $i); 
        }
    }

    //2nd loop
    for($j=0; $j<=sizeof($index_mystring2); $j++) {
      //Your code here. do note that $obj['patcher']['boxes'][$j]
      // will refer you to the data in your decoded json tree
    }
}
?>

Granted you can do this in more generic ways so it's cleaner (ie, generate both the first and second conditions into indexes) but i think you get the idea :)