1

I am using google maps geocoding api to get the following JSON object, based on an address:

{
    "results":[
        {
            "address_components":[
                {
                    "long_name":"643",
                    "short_name":"643",
                    "types":[
                        "subpremise"
                    ]
                },
                {
                    "long_name":"900",
                    "short_name":"900",
                    "types":[
                        "street_number"
                    ]
                },
                {
                    "long_name":"Folsom Street",
                    "short_name":"Folsom St",
                    "types":[
                        "route"
                    ]
                },
                {
                    "long_name":"South of Market",
                    "short_name":"South of Market",
                    "types":[
                        "neighborhood",
                        "political"
                    ]
                },
                {
                    "long_name":"San Francisco",
                    "short_name":"SF",
                    "types":[
                        "locality",
                        "political"
                    ]
                },
                {
                    "long_name":"San Francisco County",
                    "short_name":"San Francisco County",
                    "types":[
                        "administrative_area_level_2",
                        "political"
                    ]
                },
                {
                    "long_name":"California",
                    "short_name":"CA",
                    "types":[
                        "administrative_area_level_1",
                        "political"
                    ]
                },
                {
                    "long_name":"United States",
                    "short_name":"US",
                    "types":[
                        "country",
                        "political"
                    ]
                },
                {
                    "long_name":"94107",
                    "short_name":"94107",
                    "types":[
                        "postal_code"
                    ]
                },
                {
                    "long_name":"1007",
                    "short_name":"1007",
                    "types":[
                        "postal_code_suffix"
                    ]
                }
            ]
        }
    ]
}

Question

How can I get the long_name and short_name of an object in the address_components array based on a particular type?

Example

I want to get the long_name and short_name of those objects that have "locality" in their types array.

Context

I'm using this information to build an "apartment finder" application using node.js, express, and mongodb.

Considerations

I've read that underscore library is good for this.

Edit: My Thoughts

So, I have an idea how to search through the address_components array. (I can access it by results[0]), and I believe I can access types array by dot notation, but I want to search through all the types arrays of each object and return when I find an object with, let's say, types containing 'location'. How can I do this?

I'm not that well experienced parsing/looping JSON. I am learning. Any help is greatly appreciated. Thank you!

das-g
  • 9,718
  • 4
  • 38
  • 80
esanz91
  • 893
  • 2
  • 12
  • 24
  • What programming/scripting language do you use to process the JSON? Do you use any libraries or frameworks on top of that? Can you show us what code you already got and tell us how it falls short of what you want to achieve? – das-g May 11 '15 at 22:18
  • 3
    I recommend to have a look at [Access / process (nested) objects, arrays or JSON](http://stackoverflow.com/q/11922383/218196) and [Find object by id in array of javascript objects](http://stackoverflow.com/q/7364150/218196) – Felix Kling May 11 '15 at 22:21
  • @das-g I'm developing with node.js. I'm using the request module to get the requested data (body) from google, and then using JSON.parse(body), to parse. I've read that the underscore library is good to do this, but I'm not sure how. I want to be able to query based on any particular "type" I choose. – esanz91 May 11 '15 at 22:26
  • @FelixKling I have an idea how to search through the address_components component array (I can access it by results[0]), and I believe I can access types array by dot notation, but I want to search through all the types of each object and return when I find an object with, let's say, types has 'location'. How can I do this? – esanz91 May 11 '15 at 22:32
  • Pretty much as explained in the second question I linked to, e.g. http://stackoverflow.com/a/13513161/218196, except that you are not just comparing against a value, but check whether the search word is contained in the `types` array. This probably helps as well: [Javascript: Determine whether an array contains a value](http://stackoverflow.com/q/1181575/218196) – Felix Kling May 11 '15 at 22:34
  • JSON is a string format. You'll have more luck finding things like the links given by @FelixKling if you forget that your objects/arrays come from JSON. – Heretic Monkey Mar 27 '17 at 15:09

3 Answers3

3

You can use a nested .filter to get the objects containing that, combined with .map to create an array of matching objects:

var objectsContainingConditions = data.results[0].address_components.filter(function(item) {
    return item.types.filter(function(addressType) {
        return addressType == "locality";
    }).length > 0;
}).map(function(item) {
    return {
        long: item.long_name,
        short: item.short_name
    }
});

Put this into a function and pass the type if you want to reuse it:

function queryGoogleComponentsByType(type, components) {
    return components.filter(function(item) {
        return item.types.filter(function(addressType) {
            return addressType == type;
        }).length > 0;
    }).map(function(item) {
        return {
            long: item.long_name,
            short: item.short_name
        }
    });
}

var results = queryGoogleComponentsByType("locality", data.results[0].address_components);

Demo: http://jsfiddle.net/upzjth30/

tymeJV
  • 103,943
  • 14
  • 161
  • 157
0

If you want to use underscore, here is a solution that will show you how to use its primitives to achieve the result you are looking for

This will look for the first component that has a type of 'locality'

var result = _.chain(json.results)
              .pluck('address_components')
              .flatten()
              .find(function(component) {
                return  _.contains(component.types, 'locality');
              })
              .pick('long_name', 'short_name')
              .value()

Demo: https://jsfiddle.net/x9520bkx/

Jerome WAGNER
  • 21,986
  • 8
  • 62
  • 77
-2
for (var i = 0; i < data.results[0].address_components.length; i++) {
    alert(data.results[0].address_components[i].short_name);
}
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • 1
    This answer is missing an explanational part. I've seen there was non-english text, which is removed due to edits. Someone should translate it (if it's worth to). – Clijsters Mar 27 '17 at 15:09