Reputation: 33
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
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
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