Reputation: 61
I would like to switch from array 1 to array 2 according to the model below
I'm stuck on the implementation of item averages
the lessons, the number of notes and the order of the notes are random
Array 1
$tabAsso =
Array
(
[51] => Array
(
[id] => 51
[name] => JOHN
[studies] => Array
(
[0] => math
[1] => LV1
[2] => math
[3] => LV1
[4] => history
[5] => history
)
[notesC] => Array
(
[0] => 12
[1] => 18
[2] => 28
[3] => 45
[4] => 10
[5] => 18
)
[denumsC] => Array
(
[0] => 15
[1] => 60
[2] => 40
[3] => 75
[4] => 12
[5] => 45
)
)
[52] => Array
(
[id] => 52
[name] => PETER
[studies] => Array
(
[0] => sport
[1] => tech
[2] => sport
...
For example for the math average, you must read :
notesC: sum (12 + 28)
denumC sum (15 +40)
then average : (40/55) *20 = 14.5
I would like to reach this array 2
[51] => Array
(
[id] => 51
[name] => JOHN
[studies] => Array
(
[0] => math
[1] => LV1
[2] => history
)
[averages] => Array
(
[0] => 14.5
[1] => 9.3
[2] => 9.8
)
)
[52] => Array
(
[id] => 52
[name] => PETER
[studies] => Array
(
[0] => sport
[1] => tech
)
[averages] => Array
(
[0] => xx
[1] => xx
)
)
...
So far I have managed to do this ...
$tabAssoForBar = [];
foreach ($tabAsso as $id => $t) {
foreach ($t['studies'] as $k => $m) {
if (!array_key_exists($id, $tabAssoForBar)) {
$tabAssoForBar[$id] = [
'id' => $id,
'name' => $t['name'],
];
$tabAssoForBar[$id]['studies'] = [$m];
} else {
if (!in_array($m, $tabAssoForBar[$id]['studies'])) {
$tabAssoForBar[$id]['studies'][] = $m;
} else {
// nothing
}
}
}
};
I return studies with only 3 fields (math, LV1, history) but cannot create the averages field
Thanks for your help
Upvotes: 1
Views: 55
Reputation: 163277
You might use an approach to get all the indices from "study" for a all the unique values, and get the values from "notesC" and "denumsC" for those corresponding indices.
Then per unique value for "study", first sum them separately for "notesC" and "denumsC" and then divide those results and multiply the outcome by 20 to fulfill this formula:
(40/55) *20 = 14.5
You can create the result array by using the current index as the index in the new array and the unique studies and averages to it.
For example
$tabAssoForBar = [];
foreach ($tabAsso as $id => $t) {
$uniqueStudies = array_unique($t['studies']);
$averages = [];
foreach ($uniqueStudies as $uniqueStudy) {
$keysFromStudies = array_keys(array_filter($t['studies'], function($x) use ($uniqueStudy) {
return $x === $uniqueStudy;
}));
$averages[] = round(
(
array_sum(array_intersect_key($t['notesC'], array_flip($keysFromStudies))) /
array_sum(array_intersect_key($t['denumsC'], array_flip($keysFromStudies)))
) * 20,
1
);
}
$tabAssoForBar[$id] = [
'id' => $t['id'],
'name' => $t['name'],
'studies' => array_values($uniqueStudies),
'averages' => $averages
];
}
print_r($tabAssoForBar);
Output
Array
(
[51] => Array
(
[id] => 51
[name] => JOHN
[studies] => Array
(
[0] => math
[1] => LV1
[2] => history
)
[averages] => Array
(
[0] => 14.5
[1] => 9.3
[2] => 9.8
)
)
)
See a php demo
Upvotes: 1