[英]Find object in collection with fuzzy matching
I have a collection that looks something like this: 我有一个看起来像这样的集合:
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
}
}
];
… and later an object that looks like this: ......以及后来看起来像这样的对象:
const condition = {
oneCondition: true,
anotherCondition: false,
yourCondition: true,
myCondition: false
};
I'm trying to match the condition
object against the nested conditions
objects in collection
to find the one that matches so I can retrieve the name
property from the matching entry. 我正在尝试将
condition
对象与collection
中的嵌套conditions
对象进行匹配,以找到匹配的对象,这样我就可以从匹配的条目中检索name
属性。
The thing that's throwing me for a loop is the fact that the conditions
properties can have “fuzzy” values. 抛弃循环的事情是
conditions
属性可以具有“模糊”值。 By that I mean that if any properties in the source collection
are set to true
or false
they MUST match the values in condition
exactly. 我的意思是,如果源
collection
中的任何属性设置为true
或false
它们必须完全匹配condition
中的值。 But if the property in the source collection
has a value of null
it can match either true
or false
. 但是,如果源在属性
collection
的值为null
它可以匹配 true
或false
。
Example: 例:
These would match: 这些将匹配:
const condition = {
oneCondition: true,
anotherCondition: false,
yourCondition: true,
myCondition: false
};
const collection = [
…
}, {
name: 'THOSE_ITEMS',
conditions: {
oneCondition: true,
anotherCondition: false,
yourCondition: null,
myCondition: false
}
}
];
These would not: 这些不会:
const condition = {
oneCondition: true,
anotherCondition: false,
yourCondition: true,
myCondition: false
};
const collection = [
…
}, {
name: 'THAT_ITEM',
conditions: {
oneCondition: false,
anotherCondition: false,
yourCondition: true,
myCondition: false
}
}, {
…
];
Any suggestions? 有什么建议? I'm using Lodash but can't seem to imagine any solution without an overly-verbose and nested concoction.
我正在使用Lodash,但似乎无法想象没有过于冗长和嵌套的混合物的任何解决方案。
You could use Array#filter
with Array#every
for the conditions and test against null
value as wildcard. 您可以将
Array#filter
与Array#every
用于条件,并将null
值作为通配符进行测试。
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);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use lodash#filter
with lodash#isMatch
and lodash#omitBy
to match the condition
against a collection object's condition that doesn't contain any null
values. 您可以将
lodash#filter
与lodash#isMatch
和lodash#omitBy
以将condition
与不包含任何null
值的集合对象的条件进行匹配。
const result = _.filter(collection, v =>
_.isMatch(condition, _.omitBy(v.conditions, _.isNull))
);
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);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
You can filter the collecting using lodash's _.isMatchWith()
: 您可以使用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>
You can use a combination of lodash .filter() , 你可以使用lodash .filter()的组合, .every() and .isEqual() methods to loop over the
collection
and filter only items which have the same conditions as your object: .every()和.isEqual()方法循环遍历
collection
并仅过滤与对象具有相同条件的项:
_.filter(collection, function(c) {
return _.every(_.keys(condition), function(currentKey) {
return c.conditions[currentKey] === null ||
_.isEqual(c.conditions[currentKey], condition[currentKey]);
});
});
Demo: 演示:
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);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="http://underscorejs.org/underscore-min.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.