How can I find if one or more array elements match in lodash find

10,145

From the fine manual:

If an object is provided for predicate the created _.matches style callback returns true for elements that have the properties of the given object, else false.

and _.matches does element-by-element equality tests with arrays so you can't use an object predicate for what you want to do. However, you don't have to pass an object to _.find, you can pass a function:

Iterates over elements of collection, returning the first element predicate returns truthy for. The predicate is bound to thisArg and invoked with three arguments: (value, index|key, collection).

The object form of _.find that you're using just builds a predicate function behind the curtains. You can always supply your own predicate function if you need to:

_.find(users, function(value) {
    if(value.age !== 1)
        return false;
    if(!value.active)
        return false;
    if(_.intersection(value.arr, [2, 4]).length <= 0)
        return false;
    return true;
})

Of course, if your arrays aren't really sets (i.e. there could be duplicates or order matters) then you'd have to replace with _.intersection test with something that matches your specific requirements.

Demo: http://jsfiddle.net/ambiguous/vo72Lyce/

If you want this to work for arbitrary objects then you'd write your own version of _.matches (probably by starting with the current implementation) that does what you want; then you could use your version of _.matches to build the predicate function for _.find.

Share:
10,145
Redsandro
Author by

Redsandro

Lazy Media Creator #SOreadytohelp

Updated on June 18, 2022

Comments

  • Redsandro
    Redsandro almost 2 years

    Using lodash _.find(), we can see if there's a matching object in a collection.

    var users = [
      { 'user': 'barney',  'age': 36, 'active': true,  arr: [2, 3, 6, 9] },
      { 'user': 'fred',    'age': 40, 'active': false, arr: [2, 3, 6, 9] },
      { 'user': 'pebbles', 'age': 1,  'active': true,  arr: [2, 3, 6, 9] }
    ];
    

    You can provide an array, and an object matches if all values in that array are present in the collection. Notice the arr.

    _.result(_.find(users, { 'age': 1, 'active': true, 'arr': [2, 9] }), 'user');
    // Result: "pebbles"
    

    How can I match objects that have one (or more) matching array items for any array in the match object? (In this case arr.) Something similar to the $in query from MongoDB.

    _.result(_.find(users, { 'age': 1, 'active': true, 'arr': [2, 4] }), 'user');
    // Result: undefined
    // Expected: "pebbles"