简体   繁体   中英

Lodash filter matching for multiple values in nested objects

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

  • Matching obj with selectedAttributes should return the second entry in obj

What 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/lodash@4.17.10/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}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM