Reputation: 147
I have two data objects in JSON format and I'd like to merge them based on ID.
JSON 1:
{
"teams": {
"home": {
"formation": "25",
"players": [{
"id": "13112",
"name": {
"surname": "Kaiser"
},
"shirt": "1"
}]
},
"away": {
"formation": "21",
"players": [{
"id": "73560",
"name": {
"surname": "Luthe"
},
"shirt": "1"
}]
}
}
}
JSON 2:
{
"items": {
"13112": [{
"type": 31,
"time": "52:31"
}],
"73560": [{
"type": 30,
"time": "84:27"
}]
}
}
I have two objects [teams][home]
and [teams][away]
and I want to add the keys and values of [type]
and [time]
from JSON 2 based on the id of each player.
What I've done so far:
$decode_one = json_decode($str,TRUE);
$decode_two = json_decode($str2,TRUE);
foreach($decode_one['teams']['home']['players'] as $key => $value){
foreach($decode_two['items'] as $key2 => $value2){
if($value['id'] == $key2){
$decode_one['teams']['home']['players'][$key]['type'] = $value2['0']['type'];
$decode_one['teams']['home']['players'][$key]['time'] = $value2['0']['time'];
}
}
}
The output is what I've expected:
{
"teams": {
"home": {
"formation": "25",
"players": [
{
"id": "13112",
"name": {
"surname": "Kaiser"
},
"shirt": "1",
"type": 31,
"time": "52:31"
}
]
},
"away": {
"formation": "21",
"players": [
{
"id": "73560",
"name": {
"surname": "Luthe"
},
"shirt": "1"
}
]
}
}
}
But I want to add the keys and values of [type]
and [time]
from JSON 2 for [away][players]
as well.
What's the best way to approach this? Should I repeat again the same foreach loop?
Thank you
Upvotes: 0
Views: 62
Reputation: 94662
This will do what you require and parse the array only once
$str = '{"teams": {"home": {"formation": "25","players": [{"id": "13112","name": {"surname": "Kaiser"},"shirt": "1"}]},"away": {"formation": "21","players": [{"id": "73560","name": {"surname": "Luthe"},"shirt": "1"}]}}}';
$str2 = '{"items": {"13112": [{"type": 31,"time": "52:31"}],"73560": [{"type": 30,"time": "84:27"}]}}';
// leave data as an Object
$decode_one = json_decode($str);
$decode_two = json_decode($str2);
foreach($decode_one->teams as $homeOrAway => $haObj){
foreach($haObj->players as $eachPlayer => $player){
foreach($decode_two->items as $playerId => $playerInfo){
if($player->id == $playerId){
$decode_one->teams->{$homeOrAway}->players[$eachPlayer]->type = $playerInfo[0]->type;
$decode_one->teams->{$homeOrAway}->players[$eachPlayer]->time = $playerInfo[0]->time;
}
}
}
}
print_r($decode_one);
RESULT
stdClass Object
(
[teams] => stdClass Object
(
[home] => stdClass Object
(
[formation] => 25
[players] => Array
(
[0] => stdClass Object
(
[id] => 13112
[name] => stdClass Object
(
[surname] => Kaiser
)
[shirt] => 1
[type] => 31
[time] => 52:31
)
)
)
[away] => stdClass Object
(
[formation] => 21
[players] => Array
(
[0] => stdClass Object
(
[id] => 73560
[name] => stdClass Object
(
[surname] => Luthe
)
[shirt] => 1
[type] => 30
[time] => 84:27
)
)
)
)
Upvotes: 1
Reputation: 1568
To prevent repeating yourself, you could define a function that takes two arrays and merges them the way you want. Like so:
function combinePlayersData(&$playersData, $extraData) {
foreach ($playersData as $key => $value) {
if (array_key_exists($key, $extraData) {
$playersData[$key] = array_merge($value, $extraData[$key]);
}
}
}
Then just call this function twice:
$decode_one = json_decode($str, true);
$decode_two = json_decode($str2, true);
combinePlayersData($decode_one['teams']['home']['players'], $decode_two['items']);
combinePlayersData($decode_one['teams']['away']['players'], $decode_two['items']);
Upvotes: 1