How to get recursively retrieve values from a php array?

2

I take care to know how to go through a multidimensional array in php and get its values. The arrangement corresponds to a multilevel menu.

In the Array of the image I need to extract the ID of the array, and in case an ID is inside a children, know what is its parent ID, since not all the Items have children. I'll give an example below.

Here is the same arrangement in code.

[
    [
        "id"=>1,
        "children"=>[
            [
                "id"=>2,
                "children"=>[
                    [
                        "id"=>3,
                        "children"=>[
                            ["id"=>4]
                        ]
                    ],
                    [
                        "id"=>5
                    ]
                ]
            ]
        ]
    ],
    [
        "id"=>6,
        "children"=>[
            [
                "id"=>7,
                "children"=>[
                    [
                        "id"=>8,
                        "children"=>[
                            [
                                "id"=>9
                            ]
                        ]
                    ],
                    [
                        "id"=>9
                    ]
                ]
            ]
        ]
    ]
];

For example

[ ['id'=>1, 'parent' => null], ['id'=>2, 'parent' => 1], ['id'=>3, 'parent' => 2] ]
    
asked by Jedidias 24.06.2016 в 06:38
source

3 answers

1

Here is a recursive solution. The idea is to create a function that does the following:

  • Traverses all elements of the array
  • Enter its id and its parent (null for "root" elements) in an output array
  • If the node has "children"
    • Save the "id" of the node
    • Recurrently traverses the elements of "children"
    • Enter in the output array its "id" and the value of the parent (which will no longer be null)
    • Go back to step 3
  • Call the function you created with your array by passing null as the "id" value of the parent
  • This is how the code would be (commented):

    // encuentraParents: función recursiva para encontrar padres
    // $entrada: array con elementos a procesar
    // $salida: array de salida con el id del elemento y el id del padre
    // $padre: id del padre del array $entrada que se procesa
    function encuentraParents($entrada, &$salida, $padre) {
        // para cada elemento del array 
        foreach($entrada as $valor) {
            // añade una entrada al array de salida indicando su id y el de su padre
            $salida[] = array( "id" => $valor["id"], "parent" => $padre );
    
            // si el elemento tiene children
            if (isset($valor["children"] ) ) {
                // procesa los hijos recursivamente indicando el id del padre
                encuentraParents( $valor["children"], $salida, $valor["id"] );
            }
        }
    }
    
    // el array que compartiste en tu pregunta
    $objeto = [
        [
            "id"=>1,
            "children"=>[
                [
                    "id"=>2,
                    "children"=>[
                        [
                            "id"=>3,
                            "children"=>[
                                ["id"=>4]
                            ]
                        ],
                        [
                            "id"=>5
                        ]
                    ]
                ]
            ]
        ],
        [
            "id"=>6,
            "children"=>[
                [
                    "id"=>7,
                    "children"=>[
                        [
                            "id"=>8,
                            "children"=>[
                                [
                                    "id"=>9
                                ]
                            ]
                        ],
                        [
                            "id"=>9
                        ]
                    ]
                ]
            ]
        ]
    ];
    
    // el array de salida donde tendrás los valores al terminar
    $salida = array();
    
    // llamada inicial a la función recursiva con null como id del padre
    encuentraParents($objeto, $salida, null);
    

    If you make a print_r of $salida after executing that code, this is the result you get (although order may vary):

    Array
    (
        [0] => Array
            (
                [id] => 1
                [parent] => 
            )
    
        [1] => Array
            (
                [id] => 2
                [parent] => 1
            )
    
        [2] => Array
            (
                [id] => 3
                [parent] => 2
            )
    
        [3] => Array
            (
                [id] => 4
                [parent] => 3
            )
    
        [4] => Array
            (
                [id] => 5
                [parent] => 2
            )
    
        [5] => Array
            (
                [id] => 6
                [parent] => 
            )
    
        [6] => Array
            (
                [id] => 7
                [parent] => 6
            )
    
        [7] => Array
            (
                [id] => 8
                [parent] => 7
            )
    
        [8] => Array
            (
                [id] => 9
                [parent] => 8
            )
    
        [9] => Array
            (
                [id] => 9
                [parent] => 7
            )
    
    )
    
        
    answered by 25.06.2016 / 09:49
    source
    1

    I leave the following code, I hope it can help you, was based on the array_walk_recursive of php .

    Eye: You will notice that I wrote you "steps", this is a guide, so that you understand better how the script is "read", at the end of the code you will understand it better.

    <?php 
        //Este es una simulación de tu Array
        $array = [0=>["id"=>1,"children"=>[0=>["id"=>2,"children"=>[0=>["id"=>3,"children"=>[0=>["id"=>3]]]]]]]];
        $ar = $arr = array(); //Se declaran 2 arrays que contendrán los valores que vamos a iterar.
        /*Creamos una función que se apoyará el recorrido recursivo (esto mas adelante lo vemos )*/
        function a($i){ //Paso 2
         global $ar; //Accedamos al array declarado fuera de este ámbito, por eso el; global
         array_push($ar,$i); //Agregamos en valor $i al arreglo $ar.
         array_walk_recursive($ar,'b'); //Ahora hacemos recursivo el arreglo que actualmente agregamos con la función b(que esta debajo). Paso 3
        }
        //Esta es la función b la cual hicimos uso hace 2 lineas que básicamente lo que hace es apoyar el método recurviso del arreglo ar
    
        function b($a,$b){ //Paso 4
         global $arr; //Accedemos al arreglo que esta declarado fuera del ambito
         $arr[$b] = ["id"=>$a,"parent"=>($b==0?null:$b)]; //El arreglo $arr le agregamos los valores que ocupas, estableciendo la estructura que tu ocupas.
        }
        array_walk_recursive($array,"a"); // Ahora aquí es donde inicia todo el script, ya que inicialmente va hacer recursivo el array llamado; $array, Observa que te voy a listar el como va "corriendo" todo el script; Paso 1
       echo "<pre>"; 
       print_r($ar); //Imprimimos los valores que contiene el Array $ar. Paso 6
       echo "</pre>"; 
    ?>
    

    The final result will be:

     Array(
    [0]=>Array
        (
         [id]=> 1
         [parent]=>
        )
        [1]=>Array
        (
         [id]=> 2
         [parent]=>1
        )
    [2]=>Array
        (
         [id]=> 3
         [parent]=>2
        )
    [3]=>Array
        (
         [id]=> 3
         [parent]=>3
        )
    )
    
        
    answered by 24.06.2016 в 18:20
    0

    Because you do not try to save all the parents in one array, and all the children in another.

    I'll give you an example

    $arrayDatos = array();//Este seria tu array
    $arrayPadres = array();
    $contPadres = 0;
    $arrayHijos = array();
    for ($a = 0; $a < sizeof($arrayDatos); $a++)
    {
        $arrayPadres[$contPadres] = $arrayDatos[$a]['id];
        $contPadres++;
    }
    

    With the children you do the same. And then you go through the for parents and inside the children. And if the idPadre of the children's array corresponds to the id of the parent's array, you save it in a new array, and thus you have for each idFactory all the children elements.

    I hope it serves you

        
    answered by 24.06.2016 в 08:06