[英]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.