简体   繁体   English

lodash:通过另一个JSON对象过滤对象数组

[英]lodash:Filtering Array of objects by another JSON Object

I am trying to filter an array of objects using lodash by another JSON Object. 我正在尝试使用lodash通过另一个JSON对象过滤对象数组。

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 : 另一个json对象:

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 我只需要第一个对象{ 'user': 'barney', 'name': "donald", 'active': true }任何帮助将不胜感激。任何想法

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. 你的问题是,在你的iteratee功能_.forOwn ,如果仅仅是用户名或字段的一个产生一个匹配,那么整个用户对象被认为是匹配的。

To produce your expected result, you can implement a map reduce. 为了产生预期的结果,您可以实施map reduce。 Replace your code with the following (this snippet uses lodash ): 将代码替换为以下代码(此代码段使用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. 在这种情况下, _.map将检查每个用户并提供一个数组或布尔值,告诉您searchParams中的键值对是否匹配。 The reduce portion will aggregate the array of booleans into a single true or false. reduce部分将布尔数组聚合为单个true或false。 To result in true, all the key-value pairs in searchParams must produce a true value. 要得出true值, searchParams所有键值对必须产生true值。 Otherwise, the reduce portion will return false for that user, meaning they get filtered out. 否则,reduce部分将对该用户返回false,这意味着他们将被过滤掉。

Use _.every() to iterate searchParams , so if any check fails, the item is filtered out: 使用_.every()迭代searchParams ,因此,如果任何检查失败,则该项目将被滤除:

 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM