1

I have two JSON objects which I am converting to arrays. I need to join the two arrays based on a shared key ("locationCode"), and add the "address" array data from one array to the other.

After I successfully pull the JSON from a remote server using CURL, I convert them to arrays:

$json1 = json_decode($jsonresult, true);
$json2 = json_decode($jsonresult2, true);

The resulting arrays look like this:

$json1:

"maxResults":500,
"events":[
  {
     "eventCode":"20140001",
     "eventId":"72",
     "contact":{
        "contactName":"John Doe",
        "organization":"John Doe Inc.",
        "notes":""
     },
     "location":{
        "locationName":"Company Factory",
        "locationCode":"factory",
        "email":"",
        "phone":"866-123-4567",
        "tollfree":"",
        "fax":"",
        "url":"",
        "notes":""
     },
     "timezone":"(GMT-08:00) Pacific Time (US & Canada)",
     "primaryFormURL":"path/to/form"
  },
  {
     "eventCode":"20140002",
     "eventId":"73",
     "contact":{
        "contactName":"John Doe",
        "organization":"John Doe Inc.",
        "notes":""
     },
     "location":{
        "locationName":"Company HQ",
        "locationCode":"hq",
        "email":"",
        "phone":"866-123-4567",
        "tollfree":"",
        "fax":"",
        "url":"",
        "notes":""
     },
     "timezone":"(GMT-08:00) Pacific Time (US & Canada)",
     "primaryFormURL":"path/to/form"
  },
  {
     "eventCode":"20140003",
     "eventId":"74",
     "contact":{
        "contactName":"John Doe",
        "organization":"John Doe Inc.",
        "notes":""
     },
     "location":{
        "locationName":"Company HQ",
        "locationCode":"factory",
        "email":"",
        "phone":"866-123-4567",
        "tollfree":"",
        "fax":"",
        "url":"",
        "notes":""
     },
     "timezone":"(GMT-08:00) Pacific Time (US & Canada)",
     "primaryFormURL":"path/to/form"
  }
]

$json2:

"maxResults":500,
"locations":[
  {
     "numberOfRooms":null,
     "totalSpace":null,
     "address":{
        "line1":"1245 Anystreet, Building 600",
        "line2":"",
        "line3":"",
        "line4":"",
        "city":"Anycity",
        "state":"CA",
        "postalCode":"98765",
        "country":"United States",
        "intlState":""
     },
     "locationCode":"factory",
     "desc":"",
     "url":""
  },
  {
     "numberOfRooms":null,
     "totalSpace":null,
     "address":{
        "line1":"3421 Anystreet, Building 200",
        "line2":"",
        "line3":"",
        "line4":"",
        "city":"Anycity",
        "state":"CA",
        "postalCode":"97654",
        "country":"United States",
        "intlState":""
     },
     "locationCode":"hq",
     "desc":"",
     "url":""
  }
]

Now I need to join the two arrays based on the "locationCode" key matching. The join will consist of adding the "address" array data from $json2 into $json1 in the appropriate matched array position. I have been trying a variety of multidimensional array iterators, but I'm having a hard time figuring out how to actually selectively move the values I need from one array to the other. I have an iterator that finds the matches, like so:

$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($json1));
$iterator2 = new RecursiveIteratorIterator(new RecursiveArrayIterator($json2));
    foreach($iterator as $key1=>$value1) {
        if($key1=="locationCode") {
            foreach($iterator2 as $key2=>$value2) {
                if($key2=="locationCode" && $value1==$value2){
                    echo $key1.' -- '.$value1.':::'.$key2.' -- '.$value2.'<br />';
                }
            }

        }
    }

This successfully outputs the matched values. How do I now grab the "address" array data, and add it to the position within $json1 where the match was identified?

2
  • what is your criteria for matching location and address? Commented Jan 17, 2014 at 6:43
  • the "locationCode" value will be the same. Commented Jan 18, 2014 at 1:35

1 Answer 1

1

I would first process json2 into a new array with locationCode values as keys and address objects as values. Then I would walk through the events array and add the address to it if you can find a match for the location code in this array.

$json1 = json_decode($jsonresult);
$json2 = json_decode($jsonresult2);
// map locations to associative array
$addresses = array();
foreach($json2['locations'] as $location) {
    $addresses[$location->locationCode] = $location->address;
}
// add addresses to events
$events = $json1['events'];
array_walk($events, function (&$event, $key_not_used, $addresses) {
    if(array_key_exists($event->locationCode, $addresses)) {
        $event->address = $addresses[$event->locationCode];
    }
});

OP Update: Here is the final, working code...

$json1 = json_decode($jsonresult);
$json2 = json_decode($jsonresult2);

// map locations to associative array
$addresses = array();
foreach($json2->locations as $currlocation) {
    $addresses[$currlocation->locationCode] = $currlocation->address;
}

// add addresses to events
$events = $json1->events;

function add_address(&$event, $key_not_used, $searcharray) {
    if(array_key_exists($event->location->locationCode, $searcharray)) {
        $event->address = $searcharray[$event->location->locationCode];
    }
}

array_walk($events, 'add_address', $addresses);

$merged_events = json_encode($events);
print_r($merged_events);
Sign up to request clarification or add additional context in comments.

3 Comments

Do I need to add ",true" to the json_decode function? I've never understood precisely the difference in the return object with/without "true".
@MaxwellDonnelly The true option will force objects into associative arrays. I personally would recommend working with objects, as when you are "copying" address objects to events you are actually only copying a pointer to the object's memory location, so it is better from a memory management perspective. In this case I also think object are more representative of what you are working with in a real world sense. You are working with addresses with discrete properties (address lines, city, state, etc.) and events with their own properties.
Your code got me VERY close. There were a couple of syntax errors I had to clean up (missing a couple of close-parenthesis) and had to access the objects a little differently. I ended up coding the array_walk function outside the array_walk itself, and had to rename a few variable. My finished, working code is added to your answer.

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.