如何在lodash find中找到一个或多个数组元素是否匹配

时间:2015-10-15 19:02:31

标签: javascript arrays underscore.js lodash

使用lodash _.find(),我们可以看到集合中是否存在匹配的对象。

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] }
];

您可以提供一个数组,如果该数组中的所有值都存在于集合中,则对象匹配。请注意arr

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

如何匹配匹配对象中任何数组一个(或更多)匹配数组项的对象? (在这种情况下为arr。)类似于$in的{​​{1}}查询。

MongoDB

2 个答案:

答案 0 :(得分:2)

来自fine manual

  

如果为predicate提供了一个对象,则创建的_.matches样式回调会返回true以查找具有给定对象属性的元素,否则为false

_.matches使用数组进行逐元素相等的测试,因此您无法使用对象predicate来执行您想要执行的操作。但是,您不必将对象传递给_.find,您可以传递一个函数:

  

迭代collection的元素,返回第一个元素predicate返回truthy for。谓词绑定到thisArg并使用三个参数调用:(value,index | key,collection)。

您正在使用的_.find的对象形式只是在窗帘后面构建一个谓词函数。如果需要,您可以随时提供自己的谓词函数:

_.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;
})

当然,如果您的阵列没有真正设置(即可能存在重复或订单问题),那么您必须使用符合您特定要求的内容替换_.intersection测试。

演示:http://jsfiddle.net/ambiguous/vo72Lyce/

如果您希望这适用于任意对象,那么您可以编写自己的_.matches版本(可能从当前实现开始),它可以执行您想要的操作;然后,您可以使用您的_.matches版本为_.find构建谓词函数。

答案 1 :(得分:0)

据我所知,你不能在lodash中这样做。

fuzzyMatcher所做的是创建一个函数数组,其中每个函数对应于您尝试匹配的对象中的单个属性。如果该属性与用户对象中的属性匹配,则这些函数将返回true。然后fuzzyMatcher运行每个函数并获取返回true的函数的计数。如果匹配函数的数量大于或等于所需匹配的数量(在您的情况下为1),则返回true。

这看起来效果很好:

function fuzzyMatcher(collection, matchObj, minSimilarProps) {
    var matchFns = [];

    _.forOwn(matchObj, function(value, key) {
        matchFns.push(_.matchesProperty(key, value));
    });

    return _.find(collection, function(u) {
        return _.filter(matchFns, function(fn) {
            return fn(u);
        }).length >= minSimilarProps;
    });
}

//matches 1 properties
fuzzyMatcher(users, { 'age': 1, 'active': true, 'arr': [2, 4] }, 1);

//or matches 2 properties
fuzzyMatcher(users, { 'age': 1, 'active': true, 'arr': [2, 4] }, 2);

或者在你的情况下:

_.result(fuzzyMatcher(users, { 'age': 1, 'active': true, 'arr': [2, 4] }, 2), 'user');

此外,我认为您需要重新编写您想要说的“两个或更多”,因为在两种情况下,一旦或多个匹配barney,因为active = 1。