繁体   English   中英

如何根据另一个键/值对数组过滤具有复杂嵌套对象的数组?

[英]How to filter an array with complex nested objects based on another array of key/value pairs?

我有一个“产品”数组,它由多个对象组成,就像下面数组中的对象一样。 实际的数组有更多的产品,价格、图像等更多,但所有这些的结构都是相同的。

const products = [
    {
        "id": "some_id",
        "name": "some_name",
        "brand": "some_brandName",
        "inStock": true,
        "gallery": [
            "some_url_to_image"
        ],
        "category": "some_category_name",
        "attributes": [
            {
                "id": "Size",
                "name": "Size",
                "type": "text",
                "items": [
                    {
                        "displayValue": "40",
                        "value": "40",
                        "id": "40"
                    },
                    {
                        "displayValue": "41",
                        "value": "41",
                        "id": "41"
                    },
                    {
                        "displayValue": "42",
                        "value": "42",
                        "id": "42"
                    },
                    {
                        "displayValue": "43",
                        "value": "43",
                        "id": "43"
                    }
                ]
            },
            {
                "id": "Color",
                "name": "Color",
                "type": "swatch",
                "items": [
                    {
                        "displayValue": "Green",
                        "value": "#44FF03",
                        "id": "Green"
                    },
                    {
                        "displayValue": "Cyan",
                        "value": "#03FFF7",
                        "id": "Cyan"
                    },
                    {
                        "displayValue": "Blue",
                        "value": "#030BFF",
                        "id": "Blue"
                    },
                    {
                        "displayValue": "Black",
                        "value": "#000000",
                        "id": "Black"
                    },
                    {
                        "displayValue": "White",
                        "value": "#FFFFFF",
                        "id": "White"
                    }
                ]
            },
            {
                "id": "Capacity",
                "name": "Capacity",
                "type": "text",
                "items": [
                    {
                        "displayValue": "512G",
                        "value": "512G",
                        "id": "512G"
                    },
                    {
                        "displayValue": "1T",
                        "value": "1T",
                        "id": "1T"
                    }
                ]
            }
        ],
        "prices": [
            {
                "currency": {
                    "label": "USD",
                    "symbol": "$"
                },
                "amount": 55.00
            },
        ]
    },
];

我还有一个“过滤器”对象数组,其中包含一个或多个参数的值,这些参数需要用于过滤掉“产品”数组。

const filters = [
    {
        "name": "Color",
        "value": "FFFFFF"
    },
    {
        "name": "Size",
        "value": "42"
    }
];

问题

我想使用在“filters”数组中找到的值来过滤掉“products”数组以仅包含“products[index].attributes”数组包含“filters”数组中所有键/值对的产品。 例如,如果“filters”数组有一个名为“Size”和值“42”的 object,那么“products”数组应该被过滤为仅包含产品的“attributes”数组包含这些值。

我知道 Javascript 有 .filter() 方法,我知道如何使用它来过滤出一个简单的数组,但是当涉及到这样一个包含许多嵌套对象等的数组时,我不知道如何完成这个无需使用大量的嵌套函数。

过滤掉列表的最快/最简单的方法是什么?

 const products = [ { "id": "some_id", "name": "some_name", "brand": "some_brandName", "inStock": true, "gallery": [ "some_url_to_image" ], "category": "some_category_name", "attributes": [ { "id": "Size", "name": "Size", "type": "text", "items": [ { "displayValue": "40", "value": "40", "id": "40" }, { "displayValue": "41", "value": "41", "id": "41" }, { "displayValue": "42", "value": "42", "id": "42" }, { "displayValue": "43", "value": "43", "id": "43" } ] }, { "id": "Color", "name": "Color", "type": "text", "items": [ { "displayValue": "FFFFFF", "value": "FFFFFF", "id": "FFFFFF" } ] }, ], "prices": [ { "currency": { "label": "USD", "symbol": "$" }, "amount": 55.00 }, ] }, ]; const filters = [ { "name": "Color", "value": "FFFFFF" }, { "name": "Size", "value": "40" } ]; // So ofcourse we want to write a filter to filter out the products we want let filtered = products.filter( (p) => { let filteredOut = false // We have multiple filters, so we have to foreach those filters.forEach((filter) => { // Now we have to find the correct attribute to check our value with currentAttribute = p.attributes.find(product => p.name = filter.name) // We have multiple options to check with so also foreach this currentAttribute.items.forEach(item => { if (filter.value === item.value) { // If we find one, we return because we just want one hit filteredOut = true return } }) }) return filteredOut }) console.log(filtered)

我尝试使用@Wimanicesir 的答案,但它返回了一些错误('无法读取未定义')并且没有根据多个参数过滤产品列表。 相反,我编写的“filterProductList”function 过滤了产品列表并且没有抛出任何错误。 感谢@Wimanicesir 提醒我 about.find(),这帮助我缩短了之前的代码。

    const products = [
        {
            "id": "some_id",
            "name": "some_name",
            "brand": "some_brandName",
            "inStock": true,
            "gallery": [
                "some_url_to_image"
            ],
            "category": "some_category_name",
            "attributes": [
                {
                    "id": "Size",
                    "name": "Size",
                    "type": "text",
                    "items": [
                        {
                            "displayValue": "40",
                            "value": "40",
                            "id": "40"
                        },
                        {
                            "displayValue": "41",
                            "value": "41",
                            "id": "41"
                        },
                        {
                            "displayValue": "42",
                            "value": "42",
                            "id": "42"
                        },
                        {
                            "displayValue": "43",
                            "value": "43",
                            "id": "43"
                        }
                    ]
                },
                {
                    "id": "Color",
                    "name": "Color",
                    "type": "text",
                    "items": [
                        {
                            "displayValue": "FFFFFF",
                            "value": "FFFFFF",
                            "id": "FFFFFF"
                        }
                    ]
                },
            ],
            "prices": [
                {
                    "currency": {
                        "label": "USD",
                        "symbol": "$"
                    },
                    "amount": 55.00
                },
            ]
        },
    ];
    
    const filters = [
        {
            "name": "Color",
            "value": "FFFFFF"
        },
        {
            "name": "Size",
            "value": "40"
        }
    ];
    
    const filterProductList = (filters, products) => {
       return products.filter(product => filters.every(filter => {
          const key = product.attributes.find(attribute => attribute.name === filter[0]);
          const value = key !== undefined ? key.items.find(item => item.value === filter[1]) : undefined;
          const filteredProduct = value !== undefined ? product : false;
          return filteredProduct;
       }))
    }
    
    console.log(filterProductList(filters, products));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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