使用模糊匹配查找集合中的对象

时间:2017-05-10 08:11:27

标签: javascript lodash

我有一个看起来像这样的集合:

const collection = [
    {
        name: 'THIS_ITEM',
        conditions: {
            oneCondition: false,
            anotherCondition: false,
            yourCondition: false,
            myCondition: false
        }
    }, {
        name: 'THAT_ITEM',
        conditions: {
            oneCondition: false,
            anotherCondition: false,
            yourCondition: true,
            myCondition: false
        }
    }, {
        name: 'THOSE_ITEMS',
        conditions: {
            oneCondition: true,
            anotherCondition: false,
            yourCondition: null,
            myCondition: false
        }
    }
];

......以及后来看起来像这样的对象:

const condition = {
    oneCondition: true,
    anotherCondition: false,
    yourCondition: true,
    myCondition: false
};

我正在尝试将condition对象与conditions中的嵌套collection对象进行匹配,以找到匹配的对象,以便从中检索name属性匹配条目。

让我循环的事情是conditions属性可以具有“模糊”值。我的意思是,如果源collection中的任何属性设置为truefalse,则它们必须完全匹配condition中的值。但是,如果来源collection中的属性的值为null,则它可以与 <{em> truefalse匹配。

示例:

这些匹配:

const condition = {
    oneCondition: true,
    anotherCondition: false,
    yourCondition: true,
    myCondition: false
};

const collection = [
    …
    }, {
        name: 'THOSE_ITEMS',
        conditions: {
            oneCondition: true,
            anotherCondition: false,
            yourCondition: null,
            myCondition: false
        }
    }
];

这些不会:

const condition = {
    oneCondition: true,
    anotherCondition: false,
    yourCondition: true,
    myCondition: false
};

const collection = [
    …
    }, {
        name: 'THAT_ITEM',
        conditions: {
            oneCondition: false,
            anotherCondition: false,
            yourCondition: true,
            myCondition: false
        }
    }, {
    …
];

有什么建议吗?我正在使用Lodash,但似乎无法想象没有过于冗长和嵌套的混合物的任何解决方案。

4 个答案:

答案 0 :(得分:2)

您可以将Array#filterArray#every一起用于条件,并将null值作为通配符进行测试。

&#13;
&#13;
var collection = [{ name: 'THIS_ITEM', conditions: { oneCondition: false, anotherCondition: false, yourCondition: false, myCondition: false } }, { name: 'THAT_ITEM', conditions: { oneCondition: false, anotherCondition: false, yourCondition: true, myCondition: false } }, { name: 'THOSE_ITEMS', conditions: { oneCondition: true, anotherCondition: false, yourCondition: null, myCondition: false } }],
    condition = { oneCondition: true, anotherCondition: false, yourCondition: true, myCondition: false },
    result = collection.filter(o =>
        Object.keys(condition).every(k =>
            o.conditions[k] === null || o.conditions[k] === condition[k]
        )
    );

console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以lodash#filterlodash#isMatchlodash#omitBy使用{{3}}将condition与不包含任何{null的收集对象相匹配1}}值。

const result = _.filter(collection, v => 
  _.isMatch(condition, _.omitBy(v.conditions, _.isNull))
);

&#13;
&#13;
const collection = [
    {
        name: 'THIS_ITEM',
        conditions: {
            oneCondition: false,
            anotherCondition: false,
            yourCondition: false,
            myCondition: false
        }
    }, {
        name: 'THAT_ITEM',
        conditions: {
            oneCondition: false,
            anotherCondition: false,
            yourCondition: true,
            myCondition: false
        }
    }, {
        name: 'THOSE_ITEMS',
        conditions: {
            oneCondition: true,
            anotherCondition: false,
            yourCondition: null,
            myCondition: false
        }
    }
];

const condition = {
    oneCondition: true,
    anotherCondition: false,
    yourCondition: true,
    myCondition: false
};

const result = _.filter(collection, v => 
  _.isMatch(condition, _.omitBy(v.conditions, _.isNull))
);


console.log(result);
&#13;
body > div { min-height: 100%; top: 0; }
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以使用lodash的_.isMatchWith()

过滤收集

const condition = {"oneCondition":true,"anotherCondition":false,"yourCondition":true,"myCondition":false};
const collection = [{"name":"1","conditions":{"oneCondition":true,"anotherCondition":false,"yourCondition":true,"myCondition":false}},{"name":"2","conditions":{"oneCondition":true,"anotherCondition":false,"yourCondition":false,"myCondition":false}},{"name":"3","conditions":{"oneCondition":true,"anotherCondition":false,"yourCondition":null,"myCondition":false}}];

const result = collection.filter(({ conditions }) => 
  _.isMatchWith(condition, conditions, (objValue, othValue) => 
    objValue === null || othValue === null || objValue === othValue) // if at least one of the values is null or they are equal
);

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

答案 3 :(得分:0)

您可以使用lodash的组合  .filter() .every().isEqual()方法循环collection并仅过滤与您的条件相同的项目对象:

_.filter(collection, function(c) {
  return _.every(_.keys(condition), function(currentKey) {
    return c.conditions[currentKey] === null ||
      _.isEqual(c.conditions[currentKey], condition[currentKey]);
  });
});

<强>演示:

&#13;
&#13;
const collection = [{
  name: 'THIS_ITEM',
  conditions: {
    oneCondition: false,
    anotherCondition: false,
    yourCondition: false,
    myCondition: false
  }
}, {
  name: 'THAT_ITEM',
  conditions: {
    oneCondition: false,
    anotherCondition: false,
    yourCondition: true,
    myCondition: false
  }
}, {
  name: 'THOSE_ITEMS',
  conditions: {
    oneCondition: true,
    anotherCondition: false,
    yourCondition: null,
    myCondition: false
  }
}];

const condition = {
  oneCondition: true,
  anotherCondition: false,
  yourCondition: true,
  myCondition: false
};




var result = _.filter(collection, function(c) {
  return _.every(_.keys(condition), function(currentKey) {
    return c.conditions[currentKey] === null ||
      _.isEqual(c.conditions[currentKey], condition[currentKey]);
  });
});

console.log(result);
&#13;
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}
&#13;
<script src="http://underscorejs.org/underscore-min.js"></script>
&#13;
&#13;
&#13;