Get the innermost multidimensional array array

Asked

Viewed 61 times

2

I have the following json

{
  "data": {
    "card": {
      "current_phase": {
        "id": "3134719",
        "name": "Phase Final"
      },
      "child_relations": [
        {
          "cards": [
            {
              "id": "6405893",
              "current_phase": {
                "id": "3147728",
                "name": "Concluído 2"
              },
              "child_relations": [
                {
                  "pipe": {
                    "id": "458138"
                  },
                  "name": "Pipe 3 Conexão",
                  "cards": [
                    {
                      "id": "6407049",
                      "current_phase": {
                        "id": "3151152",
                        "name": "pipe 3 phase 1"
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  }
}

I always need to get the innermost array ( what’s farthest inside ), in this case it would be:

"current_phase": {
   "id": "3151152",
   "name": "pipe 3 phase 1"
}

I’ve tried several things, like the end function etc, the closest I got was that with array_column:

  $resultarray = json_decode($response, true);
  // print_r($resultarray);
  $current_phase = array_column($resultarray['data'], 'current_phase');
  print_r($current_phase);
  die();
  /* 

  Array
  (
    [0] => Array
    (
      [id] => 3134719
      [name] => Phase Final
    )
  )

  */

-- Using array_walk_recursive was the closest I got to what I need:

array_walk_recursive($resultarray, function($item, $key) {
    echo "$key holds $item\n";
  });

Return:

    title holds 9YEOCC
id holds 3134719
name holds Phase Final
name holds Pipe 2 Conexao
id holds 6405893
id holds 3147728
name holds Concluído 2
id holds 458138
name holds Pipe 3 Conexão
id holds 6407049
id holds 3151152
name holds pipe 3 phase 1
  • 1

    What if cards possess more than one array?

  • 1

    the original file is variable, that is, you do not know how many dimensions it has and the number of dimensions may vary from tag to tag?

  • @Andersoncarloswoss cards will always have only one array in this situation

  • @Rogériodec is variable, it can have no array within child_relations as it can have 2 to 3

  • Roughly speaking, I’d do it that way. 1) Read row by row; 2) With each "{" found, store the rows of this level in some variable, until you find the "}" that closes the level; 3) Continue reading and if the next block has a "}" (in addition to the "}" that closed its previous block), this means that the level has dropped, then your variable with the last stored block is the last level you need. To be clearer, just writing the code.

  • I couldn’t understand

  • You need to use recursiveness. I will try to create an answer.

  • I am using array_walk_recursive, it is the closest I have arrived, I will edit and put my result so far

Show 3 more comments

1 answer

2

Try this code (the $json variable must contain its literal string according to its post):

$nivel = 0;
$nivelMax = 0;
$posLim = 0;
for ($i = 0; $i < strlen ($json); $i++) {
    $car = substr($json, $i, 1);
    if ($car == '{') {
        $nivel++;
        if ($nivel > $nivelMax) {
            $nivelMax = $nivel;
            $posIniNivelMax = $i;
        }
    }
    if ($car == '}') {
        if ($nivel == $nivelMax)
            $posFimNivelMax = $i;
        $nivel--;
    }
    if ($car == ',') {
        $posLimAnt = $posLim;
        $posLim = $i;
    }
};
echo substr($json, $posLimAnt+1, $posFimNivelMax - $posLimAnt + 1) . '<br>';

Will show:

 "current_phase": {
    "id": "3151152",
     "name": "pipe 3 phase 1"
 }

Check also the result on Ideone.com


Browser other questions tagged

You are not signed in. Login or sign up in order to post.