I have an array of objects
const obj = [
{
"id": 20000,
"attributes": [
{
"name": "Size",
"value": "38"
},
{
"name": "Color",
"value": "Blue"
}
]
},
{
"id": 20056,
"attributes": [
{
"name": "Size",
"value": "38"
},
{
"name": "Color",
"value": "Brown"
}
]
}
]
and I have another object to match it against with
const selectedAttributes = {
"Color": "Brown",
"Size": "38"
}
the desired result after matching
obj
with selectedAttributes
should return the second entry
in objWhat I am trying
Since we cannot provide multiple values in the ._matches property this doesn't work
matchingVariations = _.filter(obj, _.flow(
_.property('attributes'),
_.partialRight(_.some, { name: ['Size', 'Color'], value: ['Brown', '38'] })
))
Expected Output
[
{
"id": 20056,
"attributes": [
{
"name": "Size",
"value": "38"
},
{
"name": "Color",
"value": "Brown"
}
]
}
]
const obj = [
{
"id": 20000,
"attributes": [
{
"name": "Size",
"value": "38"
},
{
"name": "Color",
"value": "Blue"
}
]
},
{
"id": 20056,
"attributes": [
{
"name": "Size",
"value": "38"
},
{
"name": "Color",
"value": "Brown"
}
]
}
]
const selectedAttributes = {
"Color": "Brown",
"Size": "38"
}
const selectedAttributes2 = {
"Size": "38"
}
const matchingVariations = _.filter(obj, _.flow(
_.property('attributes'),
_.partialRight(_.some, { name: 'Size', value: '38' })
))
const matchingVariations2 = _.filter(obj, _.flow(
_.property('attributes'),
_.partialRight(_.some, { name: ['Size', 'Color'], value: ['Brown', '38'] })
))
console.log(matchingVariations);
console.log(matchingVariations2);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Without a library, you could directly use Array#filter
to obtain only specific elements.
Object.entries
can be used to get the key-value pairs of the selected attributes, Array#every
can be used to ensure that all entries match a given condition, and Array#some
can be used to check that the key and value exist in the attributes array of the object.
const obj=[{id:2000,attributes:[{name:"Size",value:"38"},{name:"Color",value:"Blue"}]},{id:20056,attributes:[{name:"Size",value:"38"},{name:"Color",value:"Brown"}]}];
const selectedAttributes = {
"Color": "Brown",
"Size": "38"
}
const selectedAttributes2 = {
"Size": "38"
}
const matches = (arr, attrs)=>arr.filter(x =>
Object.entries(attrs).every(([k, v])=>
x.attributes.some(a => a.name === k && a.value === v
)));
console.log(matches(obj, selectedAttributes));
console.log(matches(obj, selectedAttributes2));
.as-console-wrapper{max-height:100%!important;top:0}