Search code examples
javascripttypescriptgoogle-mapsgoogle-places-apigoogle-places-autocomplete

better way to check if a value is inside of a nested array - Javascript


I'm working with Google Places API. I noticed when I enter establishment not always have a zipcode, country, city and if they do they aren't always in the same index inside the address_components array.

Now, I'm trying to find if it has any of the things listed above, and if it does return the value. Is there a better way to achieve this:

getPlaceTypeValue(addressComponents: Places[], type: string): string {
    let value = null;
    for (const [i] of addressComponents.entries()) {
      if (addressComponents[i].types.includes(type)) {
        value = addressComponents[i].long_name;
        break;
      }
    }
    return value;
  } 
console.log(this.placesService.getPlaceTypeValue(
address.address_components, 'postal_code'));
//Returns 77500

Data

[
      {
        "long_name": "Hotel Zone",
        "short_name": "Hotel Zone",
        "types": [
          "sublocality_level_1",
          "sublocality",
          "political"
        ]
      },
      {
        "long_name": "Kukulcan Boulevard",
        "short_name": "Kukulcan Boulevard",
        "types": [
          "neighborhood",
          "political"
        ]
      },
      {
        "long_name": "Cancún",
        "short_name": "Cancún",
        "types": [
          "locality",
          "political"
        ]
      },
      {
        "long_name": "Quintana Roo",
        "short_name": "Q.R.",
        "types": [
          "administrative_area_level_1",
          "political"
        ]
      },
      {
        "long_name": "Mexico",
        "short_name": "MX",
        "types": [
          "country",
          "political"
        ]
      },
      {
        "long_name": "77500",
        "short_name": "77500",
        "types": [
          "postal_code"
        ]
      }
    ]

Solution

  • First of all, I would change this:

    for (const [i] of addressComponents.entries()) {
      if (addressComponents[i].types.includes(type)) {
    

    to this:

    for (const {types} of addressComponents) {
      if (types.includes(type)) {
    

    Or if you like a more functional approach, then use Array#find in a one-line return statement:

    return (addressComponents.find(({types}) => types.includes(type)) || {}).long_name || null;
    

    The || null part is only needed if a return value of undefined would not be OK for you.

    Speed

    If in your question "better" means "faster", then go for the old-school for loop:

    for (let i = 0, len = addressComponents.length; i < len; i++) {
      if (addressComponents[i].types.includes(type)) {