jd268
jd268

Reputation: 33

How to restructure an array so that a sub array key becomes array key

First time posting here and really need some help. Relatively new to php I have an array that I'd like to restructure. I have subjects at top level with students in a sub array. I'd like to restructure so that Students are at the top level with subjects in a sub array.

$startingArray = [
    [   "subject" => "Physics",
        "student" => [
            ["id" => "00003", "Name" => "Peter", "email" => "[email protected]",],
            ["id" => "00004", "Name" => "Mary", "email" => "[email protected]",],
            ["id" => "00005", "Name" => "Jane", "email" => "[email protected]",],
        ]
    ],
    [   "subject" => "Chemistry",
        "student" => [
            ["id" => "00003", "Name" => "Peter", "email" => "[email protected]",],
            ["id" => "00004", "Name" => "Mary", "email" => "[email protected]",],
            ["id" => "00005", "Name" => "Jane", "email" => "[email protected]",],
        ]
    ],
    [   "subject" => "Mathematics",
        "student" => [
            ["id" => "00003", "Name" => "Peter", "email" => "[email protected]",],
            ["id" => "00006", "Name" => "Fred", "email" => "[email protected]",],
            ["id" => "00007", "Name" => "Wilma", "email" => "[email protected]",],
        ]
    ],
    [   "subject" => "Biology",
        "student" => [
            ["id" => "00004", "Name" => "Mary", "email" => "[email protected]",],
            ["id" => "00006", "Name" => "Fred", "email" => "[email protected]",],
            ["id" => "00008", "Name" => "Alison", "email" => "[email protected]",],
        ]
    ]
];

I want my new array to be like this;

$endingArray = [
     "students" => [
         [   "id" => "00003",
             "Name" => "Peter",
             "email" => "[email protected]",
             "subjects" => [ "Physics", "Chemistry", "Mathematics", ],
         ],
         [   "id" => "00004",
             "Name" => "Mary",
             "email" => "[email protected]",
             "subjects" => [ "Physics", "Chemistry", "Biology", ],
         ],
         [   "id" => "00005",
             "Name" => "Jane",
             "email" => "[email protected]",
             "subjects" => [ "Physics", "Chemistry", ],
         ],
         [   "id" => "00006",
             "Name" => "Fred",
             "email" => "[email protected]",
             "subjects" => [ "Mathematics", "Biology", ],
         ],
         [   "id" => "00007",
             "Name" => "Wilma",
             "email" => "[email protected]",
             "subjects" => [ "Mathematics", "Biology", ],
         ],
         [   "id" => "00008",
             "Name" => "Alison",
             "email" => "[email protected]",
             "subjects" => [ "Physics", "Biology", ],
         ],
     ],
];

I'm trying a 2 stage process. First is to create the new students array without the subjects. This works fine.

Then I'm trying to append the subjects but I know my logic is wrong and the code I have just creates a new row for each student and each subject.

foreach ( $startingArray as $row ) {
    $students = $row['student'];
    foreach ($students as $student) {
        if (!in_array($student, $studentsArray)) {
            $studentsArray[] = $student;
        }
    }
}

the second step just produces garbage

    $s1 = $student['id'];
    foreach ($startingArray as $row) {
        $subject = $row['subject'];
        $students = $row['student'];
        foreach ($students as $s2) {
            if ($s2['id]'] = $s1) {
                $student['subjects'] = $subject;
                array_push($studentsArray, $student);
            }
        }
    }
}

Any help appreciated!

Upvotes: 3

Views: 63

Answers (2)

Amós Assis
Amós Assis

Reputation: 161

Case you need to maintain a sequential id like your example do this

$newArray = [];
foreach ($startingArray as $item) {
    foreach ($item["student"] as $student) {
        $filter = array_filter($newArray, function ($d) use ($student) {
            return ($d["id"] == $student["id"]);
        });
        if (!$filter) {
            $student["subjects"][] = $item['subject'];
            $newArray[] = $student;
        } else {
            $newArray[key($filter)]["subjects"][] = $item["subject"];
        }
    }
}

$finalArray = [
    'students' => $newArray
];

The final result will be

Array
(
    [students] => Array
        (
            [0] => Array
                (
                    [id] => 00003
                    [Name] => Peter
                    [email] => [email protected]
                    [subjects] => Array
                        (
                            [0] => Physics
                            [1] => Chemistry
                            [2] => Mathematics
                        )

                )

            [1] => Array
                (
                    [id] => 00004
                    [Name] => Mary
                    [email] => [email protected]
                    [subjects] => Array
                        (
                            [0] => Physics
                            [1] => Chemistry
                            [2] => Biology
                        )

                )

            [2] => Array
                (
                    [id] => 00005
                    [Name] => Jane
                    [email] => [email protected]
                    [subjects] => Array
                        (
                            [0] => Physics
                            [1] => Chemistry
                        )

                )

            [3] => Array
                (
                    [id] => 00006
                    [Name] => Fred
                    [email] => [email protected]
                    [subjects] => Array
                        (
                            [0] => Mathematics
                            [1] => Biology
                        )

                )

            [4] => Array
                (
                    [id] => 00007
                    [Name] => Wilma
                    [email] => [email protected]
                    [subjects] => Array
                        (
                            [0] => Mathematics
                        )

                )

            [5] => Array
                (
                    [id] => 00008
                    [Name] => Alison
                    [email] => [email protected]
                    [subjects] => Array
                        (
                            [0] => Biology
                        )

                )

        )

)

Upvotes: 1

u_mulder
u_mulder

Reputation: 54841

Here what you can do:

$newArray = [];
foreach ($startingArray as $item) {
    foreach ($item['student'] as $student) {
        if (empty($newArray[$student['id']])) {
            $student['subjects'] = [];
            $newArray[$student['id']] = $student;
        }

        $newArray[$student['id']]['subjects'][] = $item['subject'];
    }
}

Sample fiddle here.

Upvotes: 2

Related Questions