1

I'm facing some trouble while trying to manipulate two arrays with some similarities.

The first array has this structure:

$modules = [
    [
        "id_modulo" => "114",
        "nome_modulo" => "1. Acessos"
    ],
    [
    
        "id_modulo" => "118",
        "nome_modulo" => "4. Área de Vivência"
    ],
    [
        "id_modulo" => "128",
        "nome_modulo" => "14. Supressão"
    ]
];

And the second one's structure:

$items = [
    [
        "id_modulo" => "114",
        "id_pergunta" => "547",
        "pergunta" => "Example",
        "resposta" => "C"
    ],
    [
        "id_modulo" => "114",
        "id_pergunta" => "548",
        "pergunta" => "Example",
        "resposta" => "C"
    ],
    [
        "id_modulo" => "118",
        "id_pergunta" => "549",
        "pergunta" => "Example",
        "resposta" => "C"
    ],
    [
        "id_modulo" => "114",
        "id_pergunta" => "550",
        "pergunta" => "Example",
        "resposta" => "C"
    ],
];

What I am trying to do is append the second array into the first one, where id_modulo is the same. Basically the first array has some modules details, and the second one has questions and answers of each module.

So all the questions from the second array that corresponds with the id_module node must be inserted into the first array.

I already tried lots of examples using array_merge, looping with array_push, also followed this tutorial but could not achieve anything like the final result that I expect.

Example of output:

[0]=>
  array(2) {
    ["id_modulo"]=>
    string(3) "114"
    ["nome_modulo"]=>
    string(16) "1. Acessos"
    ["items"]=>
      [0]=>
        array(4) {
          ["id_modulo"]=>
          string(3) "114"
          ["id_pergunta"]=>
          string(3) "547"
          ["pergunta"]=>
          string(58) "Example"
          ["resposta"]=>
          string(1) "C"
        }
      [1]=>
      array(4) {
        ["id_modulo"]=>
        string(3) "114"
        ["id_pergunta"]=>
        string(3) "548"
        ["pergunta"]=>
        string(57) "Example"
        ["resposta"]=>
        string(1) "C"
      }
  }
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
jvbs
  • 417
  • 2
  • 11
  • 27

2 Answers2

2

First create a temp array to store index of a given id_modulo from first array. So while pushing an item from second array to first array, we don't have to search every time.

$arrModuleIndex     =   [];
// $arr here is your first array.
foreach($arr as $key => $data){
    $arrModuleIndex[$data['id_modulo']] = $key;
}

Output:
Array
(
    [114] => 0
    [118] => 1
    [128] => 2
)

Now loop through second array and push it to items of first array at index based on temporary array.

// Here $arr2 is your second array
foreach($arr2 as $data){
    $arr[$arrModuleIndex[$data['id_modulo']]]['items'][] = $data;
}

Output:
Array
(
    [0] => Array
        (
            [id_modulo] => 114
            [nome_modulo] => 1. Acessos
            [items] => Array
                (
                    [0] => Array
                        (
                            [id_modulo] => 114
                            [id_pergunta] => 547
                            [pergunta] => Example
                            [resposta] => C
                        )

                    [1] => Array
                        (
                            [id_modulo] => 114
                            [id_pergunta] => 548
                            [pergunta] => Example
                            [resposta] => C
                        )

                    [2] => Array
                        (
                            [id_modulo] => 114
                            [id_pergunta] => 550
                            [pergunta] => Example
                            [resposta] => C
                        )

                )

        )

    [1] => Array
        (
            [id_modulo] => 118
            [nome_modulo] => 4. Área de Vivência
            [items] => Array
                (
                    [0] => Array
                        (
                            [id_modulo] => 118
                            [id_pergunta] => 549
                            [pergunta] => Example
                            [resposta] => C
                        )

                )

        )

    [2] => Array
        (
            [id_modulo] => 128
            [nome_modulo] => 14. Supressão
        )

)
Dark Knight
  • 6,116
  • 1
  • 15
  • 37
0

You can elegantly generate the desired result by merging the second array into the first array (so that the module rows are iterated first), then push rows into the result with first level keys based on the modulo_id. If an encountered row contains a nome_modulo element, it has parent data, otherwise it has item/child data.

I am adding an items element containing an empty array to ensure that all rows in the output have a consistent structure.

If you wish to re-index the result array to remove the associative first level keys, call array_values() on it.

Code: (Demo)

$result = [];
foreach (array_merge($modules, $items) as $row) {
    if (isset($row['nome_modulo'])) {
        $result[$row['id_modulo']] = $row + ['items' => []];
    } else {
        $result[$row['id_modulo']]['items'][] = $row;
    }
}
var_export(array_values($result));
mickmackusa
  • 43,625
  • 12
  • 83
  • 136