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.
The thing that’s throwing me for a loop is the fact that the conditions
properties can have “fuzzy” values. 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. But if the property in the source collection
has a value of null
it can match either true
or 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.
You could use Array#filter
with Array#every
for the conditions and test against null
value as wildcard.
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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With