3
\$\begingroup\$

is there an easier/more efficient way to join two JSON objects on a common property than this? It's a GeoJSON file (basically an array of objects), and I want to pull in a property from another JSON file (array of objects) based on a common property, similar to a SQL SELECT a.*, b.* FROM a LEFT JOIN b ON a.id = b.a_id

$.when(
    $.getJSON('https://data.phila.gov/resource/bbgf-pidf.geojson'),
    $.getJSON('https://data.phila.gov/resource/r24g-zx3n.json?%24select=count(*)%20as%20value%2C%20%3A%40computed_region_bbgf_pidf%20as%20label&%24group=%3A%40computed_region_bbgf_pidf&%24order=value%20desc')
).done(function(responseGeojson, responseData) {
    var data = responseData[0]
    var geojson = responseGeojson[0]

    // Create hash table for easy reference
    var dataHash = {}
    data.forEach(function(item) {
        if(item.label) dataHash[item.label] = item.value
    })

    // Add value from hash table to geojson properties
    geojson.features.forEach(function(item) {
        item.properties.incidents = +dataHash[item.properties._feature_id] || null 
    })

    console.log(geojson)
})
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

I notice a query on one of your urls. I suggest you use jQuery's $.param to construct the query cleanly.

For your first loop, you could use reduce instead of forEach to generate your hash. Additionally, you might want kill NaN early. You don't want to be carrying NaN in any data structure, otherwise you'll get some unexpected NaN in your code.

var dataHash = data.reduce(function(hash, item) {
  var value = +item.value
  hash[item.label] = isNaN(value) ? null : value;
  return hash;
}, {});

geojson.features.forEach(function(item) {
  item.properties.incidents = dataHash[item.properties._feature_id];
});

As for efficiency, I guess that's about it. You don't want to be nesting a lookup inside the other loop. Two separate loops is better then one nested inside another.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks Joseph! Didn't realize reduce could be used that way \$\endgroup\$ Commented Nov 12, 2015 at 13:03
1
\$\begingroup\$

Just want to follow up with something I learnt today: The creation of a hash map can be accomplished more easily using lodash or underscore's indexOf function.

$.when(
    $.getJSON('https://data.phila.gov/resource/bbgf-pidf.geojson'),
    $.getJSON('https://data.phila.gov/resource/r24g-zx3n.json?%24select=count(*)%20as%20value%2C%20%3A%40computed_region_bbgf_pidf%20as%20label&%24group=%3A%40computed_region_bbgf_pidf&%24order=value%20desc')
).done(function(responseGeojson, responseData) {
    var data = responseData[0]
    var geojson = responseGeojson[0]

    // Create hash table for easy reference
    var dataHash = _.indexBy(data, 'label')

    // Add value from hash table to geojson properties
    geojson.features.forEach(function(item) {
        item.properties.incidents = +dataHash[item.properties._feature_id].value || null 
    })

    console.log(geojson)
})
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.