-1

I have a two dimensional array of students from different schools and countries. I want them to be grouped by name of school and country.

How can I create the nested key structure?

Example:

$students = [
  [
    "country" => "japan",
    "school"  => "kyoto university",
    "name"    => "Naruto Uzumaki"
  ],
  [
    "country" => "usa",
    "school"  => "harvard university",
    "name"    => "Naruto Uzumaki"
  ], 
  [
    "country" => "japan",
    "school"  => "tokyo university",
    "name"    => "sasuke Uchiha"
  ],
  [
    "country" => "japan",
    "school"  => "tokyo university",
    "name"    => "kakashi hatake"
  ],
];

Desired result:

[
  “japan” => [
      “kyoto university” => [
          [
            “country” => “japan”,
            “school”  => “kyoto university”,
            “name”    => “Naruto Uzumaki”
          ],
      ],

      “tokyo university” => [
          [
            “country” => “japan”,
            “school”  => “tokyo university”,
            “name”    => “sasuke Uchiha”
          ],
          [
            “country” => “japan”,
            “school”  => “tokyo university”,
            “name”    => “kakashi hatake”
          ],
      ],

   ],
   

   “usa” => [
       “harvard university” => [
           [
             “country” => “usa”,
             “school”  => “harvard university”,
             “name”    => “Naruto Uzumaki”
           ],
       ]
     ]

]

2 Answers 2

1

Pretty much creating an object or using an existing one. First create country object if not exists, then create school object under it (if not exists) then push to it.

$result = [];
foreach ($students as $student) {
    $country = $student['country'];
    $school = $student['school'];
    $result[$country] = isset($result[$country]) ? $result[$country] : [];
    $result[$country][$school] = isset($result[$country][$school]) ? $result[$country][$school] : [];
    $result[$country][$school][] = $student;
}
print_r($result);

Output:

Array
(
    [japan] => Array
        (
            [kyoto university] => Array
                (
                    [0] => Array
                        (
                            [country] => japan
                            [school] => kyoto university
                            [name] => Naruto Uzumaki
                        )

                )

            [tokyo university] => Array
                (
                    [0] => Array
                        (
                            [country] => japan
                            [school] => tokyo university
                            [name] => sasuke Uchiha
                        )

                    [1] => Array
                        (
                            [country] => japan
                            [school] => tokyo university
                            [name] => kakashi hatake
                        )

                )

        )

    [usa] => Array
        (
            [harvard university] => Array
                (
                    [0] => Array
                        (
                            [country] => usa
                            [school] => harvard university
                            [name] => Naruto Uzumaki
                        )

                )

        )

)
Sign up to request clarification or add additional context in comments.

Comments

1
  • Loop over each row
  • Create convenient variables from the row's associative elements with extract()
  • Push the row into the nested associative structure using two of the three generated variables

Code: (Demo)

$result = [];
foreach ($students as $student) {
    extract($student);
    $result[$country][$school][] = $student;
}
var_export($result);

It is not at all necessary to instantiate/declare parent elements before pushing child elements when using square brace pushing syntax. If you are using array_push(), the parent element must be declared in advance.

There are more abstract and less attractive ways to code this task using array_reduce() or array destructuring:

Related:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.