簡體   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