JTech
JTech

Reputation: 3570

lodash: How to do case insensitive _.find()

I have a complex data structure, with nested arrays and I need to find an element with a string value using a case insensitive search.

I've started using lodash due to the simple syntax to perform nested queries - it works great but the search is case sensitive.

I want to find an "address_components" element with a "types" value of 'route' and "long_name" value equal to a parameter called 'targetStreet'.

Here is the lodash code I have so far:

    var result = _.find(geocodeResult,
        {
            'address_components': [
                {
                    types: ['route'],
                    'long_name': targetStreet
                }
            ]
        });

Question: How can I make the matching of the "long_name" property case insensitive?

Below is an example of the 'geocodeResult' data structure (its actually a Google Geocoding Result object).

Note that this data structure is dynamic...Google will return the most specific result it can, but if it can't find a match for a street, then it wont return the street component e.g. the "types" array within "address_components" has non-deterministic values.

    [
  {
    "address_components": [
      {
        "long_name": "V&a Lane",
        "short_name": "V&a Ln",
        "types": [
          "route"
        ]
      },
      {
        "long_name": "Coonawarra",
        "short_name": "Coonawarra",
        "types": [
          "locality",
          "political"
        ]
      },
      {
        "long_name": "Wattle Range Council",
        "short_name": "Wattle Range",
        "types": [
          "administrative_area_level_2",
          "political"
        ]
      },
      {
        "long_name": "South Australia",
        "short_name": "SA",
        "types": [
          "administrative_area_level_1",
          "political"
        ]
      },
      {
        "long_name": "Australia",
        "short_name": "AU",
        "types": [
          "country",
          "political"
        ]
      },
      {
        "long_name": "5263",
        "short_name": "5263",
        "types": [
          "postal_code"
        ]
      }
    ],
    "formatted_address": "V&a Ln, Coonawarra SA 5263, Australia",
    "geometry": {
      "bounds": {
        "south": -37.3238134,
        "west": 140.8154452,
        "north": -37.3228868,
        "east": 140.97295129999998
      },
      "location": {
        "lat": -37.3233904,
        "lng": 140.89510410000003
      },
      "location_type": "GEOMETRIC_CENTER",
      "viewport": {
        "south": -37.3246990802915,
        "west": 140.8154452,
        "north": -37.3220011197085,
        "east": 140.97295129999998
      }
    },
    "partial_match": true,
    "place_id": "EiVWJmEgTG4sIENvb25hd2FycmEgU0EgNTI2MywgQXVzdHJhbGlh",
    "types": [
      "route"
    ]
  },
  {
    "address_components": [
      {
        "long_name": "V&a Lane",
        "short_name": "V&a Ln",
        "types": [
          "route"
        ]
      },
      {
        "long_name": "Coonawarra",
        "short_name": "Coonawarra",
        "types": [
          "locality",
          "political"
        ]
      },
      {
        "long_name": "Wattle Range Council",
        "short_name": "Wattle Range",
        "types": [
          "administrative_area_level_2",
          "political"
        ]
      },
      {
        "long_name": "South Australia",
        "short_name": "SA",
        "types": [
          "administrative_area_level_1",
          "political"
        ]
      },
      {
        "long_name": "Australia",
        "short_name": "AU",
        "types": [
          "country",
          "political"
        ]
      },
      {
        "long_name": "5263",
        "short_name": "5263",
        "types": [
          "postal_code"
        ]
      }
    ],
    "formatted_address": "V&a Ln, Coonawarra SA 5263, Australia",
    "geometry": {
      "bounds": {
        "south": -37.3238134,
        "west": 140.8154452,
        "north": -37.3228868,
        "east": 140.97295129999998
      },
      "location": {
        "lat": -37.3233904,
        "lng": 140.89510410000003
      },
      "location_type": "GEOMETRIC_CENTER",
      "viewport": {
        "south": -37.3246990802915,
        "west": 140.8154452,
        "north": -37.3220011197085,
        "east": 140.97295129999998
      }
    },
    "partial_match": true,
    "place_id": "EiVWJmEgTG4sIENvb25hd2FycmEgU0EgNTI2MywgQXVzdHJhbGlh",
    "types": [
      "route"
    ]
  }
]

Upvotes: 5

Views: 19039

Answers (3)

Vinay
Vinay

Reputation: 2339

This is how you can search case insensitive using lodash _.find() function

const propertyName = "Basic";
const findName = _.find(this.object, item => {
        return item.name.toLowerCase() === propertyName.toLowerCase();
    });

Upvotes: 5

Freez
Freez

Reputation: 7568

The way you use lodash.find correspond to lodash.match shorthand (https://lodash.com/docs/4.17.4#find), unfortunately you can't pass regexp or function to get an insensitive search in your object properties.

You have to write something like that to perform the search (assuming targetStreet in lower case) :

var result = _.find(geoCodeResult, function (result) {
   return _.find(result.address_components, function(component) {
      return _.includes(component.types, 'route')
        && component.long_name.toLowerCase() === targetStreet;
   });
});

You can also write it without lodash, using ES6 syntax + Array.prototype.find and Array.prototype.includes (for recent browsers)

const result = geoCodeResult.find(result => 
   result.address_components.find(({ types, long_name }) => 
      types.includes('route') && long_name.toLowerCase() === targetStreet
   ));

Upvotes: 3

fubar
fubar

Reputation: 17378

Convert the two values to the same case before comparison.

var search = 'Australia'.toLowerCase();

var result = _.find(geoCodeResult, function (location) {
    return location.long_name.toLowerCase() === search;
});

Upvotes: 13

Related Questions