0

I am trying to filter an array of objects using lodash by another JSON Object.

var users = [
  { 'user': 'barney', 'name': "donald", 'active': true },
  { 'user': 'joe', 'name': "john", 'active': false },
  { 'user': 'fred', 'name': "peri", 'active': false },
  { 'user': 'fred', 'name': "aru", 'active': false },
  { 'user': 'fred', 'name': "teena", 'active': false },
  { 'user': 'fred', 'name': "nill", 'active': false },
  { 'user': 'fred', 'name': "duck", 'active': false },
  { 'user': 'barney', 'name': "resaj", 'active': false },
  { 'user': 'pebbles', 'name': "jee",  'active': true }
];

another json Object :

var searchParams = { 'user': 'ba', 'name': "don"}

If First array object's user contains second object's user and 1st objects name contains 2nd objects name than i want the object.I tried this code but it returns with OR condition not AND Condition.

_.filter(users, function(o) {
                    var checkFlag = false;
                    _.forOwn(searchParams, function(v,k) {
                        if(_.includes(o[k],v)){
                            checkFlag = true;
                            return false;
                        }
                    });
                    return checkFlag;
                });

This returns below results

[{ 'user': 'barney', 'name': "donald", 'active': true },{ 'user': 'barney', 'name': "resaj", 'active': false }]

I want only first object { 'user': 'barney', 'name': "donald", 'active': true } Any help would be appreciated.Any idea

2 Answers 2

2

Your issue is that in the iteratee function for your _.forOwn, if just the one of the user or name fields produces a match, then the whole user object is considered a match.

To produce your expected result, you can implement a map reduce. Replace your code with the following (this snippet uses lodash):

_.filter(users, function(o) {
    return _.map(searchParams, function(v,k) {
      return _.includes(o[k],v)
    }).reduce(function(isMatch, keyValueMatch){
      return isMatch && keyValueMatch
    }, true);
});

In this case, the _.map will check each user and provide an array or booleans telling you whether a key-value pair in searchParams is a match. The reduce portion will aggregate the array of booleans into a single true or false. To result in true, all the key-value pairs in searchParams must produce a true value. Otherwise, the reduce portion will return false for that user, meaning they get filtered out.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @julian soro, works like charm,tried with more than two search params too. :)
2

Use _.every() to iterate searchParams, so if any check fails, the item is filtered out:

var users = [
  { 'user': 'barney', 'name': "donald", 'active': true },
  { 'user': 'joe', 'name': "john", 'active': false },
  { 'user': 'fred', 'name': "peri", 'active': false },
  { 'user': 'fred', 'name': "aru", 'active': false },
  { 'user': 'fred', 'name': "teena", 'active': false },
  { 'user': 'fred', 'name': "nill", 'active': false },
  { 'user': 'fred', 'name': "duck", 'active': false },
  { 'user': 'barney', 'name': "resaj", 'active': false },
  { 'user': 'pebbles', 'name': "jee",  'active': true }
];

var searchParams = { 'user': 'ba', 'name': "don"};

var result = _.filter(users, function(o) {
  return _.every(searchParams, function(v, k) {
    return _.includes(o[k], v);
  });
});

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.