[英]How can I filter a nested object with dynamic filters using Lodash or plain javascript?
我有以下数据:
const products = [{
name: "Product 1",
options: [
{
id: 1,
optionName: "Color",
value: "Red"
},
{
id: 2,
optionName: "Size",
value: "Small"
}
]},
{
name: "Product 2",
options: [
{
id: 1,
optionName: "Color",
value: "Red"
},
{
id: 2,
optionName: "Size",
value: "Large"
}
]}];
我有一个过滤器 object,它是动态创建的:
let selectedFilters = {"Color":"Red", "Size":"Small"};
我只想获得满足 selectedFilters object 中指定的所有标准的产品。 在示例中,我应该只得到“产品 1”
这是我迄今为止尝试过的,但这些都不是我需要的:
let filteredProducts = [];
let keys = Object.keys(selectedFilters);
keys.forEach(function(filterKey) {
let f = _.filter(products, function(o) {
let flag = false;
let searchFilterKey = selectedFilters[filterKey];
let index = o.options.findIndex(o=> o.optionName == filterKey && o.value == searchFilterKey);
if (index > 0)
return o;
});
filteredProducts = f;
});
products.filter(p =>
Object.keys(selectedFilters).every(k =>
{
return p.options.filter(o => o.optionName == k && o.value == selectedFilters[k]);
}));
您可以在数组中获取过滤器的值,并使用匹配条件运行每个 function。 由于“值”是此处的重要属性,因此使用它来针对选定过滤器运行其值。
如果您是标准的一部分,则对键执行相同操作
const products = [{ name: "Product 1", options: [{ id: 1, optionName: "Color", value: "Red" }, { id: 2, optionName: "Size", value: "Small" } ] }, { name: "Product 2", options: [{ id: 1, optionName: "Color", value: "Red" }, { id: 2, optionName: "Size", value: "Large" } ] } ] let selectedFilters = { "Color": "Red", "Size": "Small" }; const arrFilterValues = Object.values(selectedFilters); const arrFilterKeys = Object.keys(selectedFilters); const result = products.filter(x => { return x.options.every(y=> arrFilterValues.includes(y['value']) && arrFilterKeys.includes(y['optionName'])) }) console.log(result)
您可以根据 object 的条目进行过滤。
const products = [{ name: "Product 1", options: [ { id: 1, optionName: "Color", value: "Red" }, { id: 2, optionName: "Size", value: "Small" } ]}, { name: "Product 2", options: [ { id: 1, optionName: "Color", value: "Red" }, { id: 2, optionName: "Size", value: "Large" } ]}]; let selectedFilters = {"Color":"Red", "Size":"Small"}; let entries = Object.entries(selectedFilters); const res = products.filter(({options})=> entries.every(([k,v])=>options.some(o=>o.optionName===k && o.value === v))); console.log(res);
您可以使用Array#filter 、 Array#every和Array#some获得结果。 过滤器数组可以动态扩展,不需要对其进行排序或所有过滤器属性都存在。
我过滤了产品数组。 这里对于每个将被选中的产品,过滤器阵列的所有过滤器都将被填充。 对于每个过滤器标准,我都会查看此标准是否适用于该产品的某些选项。 为此具有要匹配的选项名称和值。
function myFilter(array, filters) { return array.filter(({options}) => Object.entries(filters).every(([key, value]) => options.some((option) => option.optionName===key && option.value===value ) ) ); } const products = [{ name: "Product 1", options: [ { id: 1, optionName: "Color", value: "Red" }, { id: 2, optionName: "Size", value: "Small" } ]}, { name: "Product 2", options: [ { id: 1, optionName: "Color", value: "Red" }, { id: 2, optionName: "Size", value: "Large" } ]}]; let filters= {"Color":"Red", "Size":"Small"}; console.log(myFilter(products, filters));
您可以尝试使用Array.filter ,然后使用Array.every function foreach product.options
来检查它的属性是否存在于 selectedFilters object 中。
const products = [{
name: "Product 1",
options: [
{
id: 1,
optionName: "Color",
value: "Red"
},
{
id: 2,
optionName: "Size",
value: "Small"
}
]
},
{
name: "Product 2",
options: [
{
id: 1,
optionName: "Color",
value: "Red"
},
{
id: 2,
optionName: "Size",
value: "Large"
}
]
}
];
let selectedFilters = {"Color":"Red", "Size":"Small"};
let filteredProducts = products.filter(product => {
return product.options.every(({ optionName, value }) => !!selectedFilters[optionName] && selectedFilters[optionName] === value);
});
console.log(filteredProducts);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.