我正在尝试根据多个过滤器数组来过滤项目数组。每个项目都有一个过滤器选择,我只需要显示与所有选定过滤器匹配的过滤器即可。
const selectedFilters = {
color: ["Red", "Blue"],
type: ["Shirt"],
size: ["M"]
};
const items = [
{
name: "Item 1",
filters: {
color: ["Red", "Blue", "Black"],
type: ["Shirt"],
size: ["M"]
}
},
{
name: "Item 2",
filters: {
color: ["Red"],
type: ["Pants"],
size: ["M"]
}
}
];
这就是我一直试图解决的方式。对所有项目进行过滤-对于每个不为空的过滤器类别,请遍历所有过滤器词,并检查该项目是否与所有词均匹配。
const filterItems = (items, selectedFilters) => {
const filterKeys = Object.keys(selectedFilters);
return items.filter(item => {
return filterKeys.every(key => {
// Ignore empty filters
if (!selectedFilters[key].length) {
return true;
}
return selectedFilters[key].every(filterWord => {
item.filters[key].includes(filterWord);
});
});
});
};
filterItems(items, selectedFilters);
返回一个空数组,应返回一个带有“ Item 1”对象的数组。
答案 0 :(得分:0)
您可以创建selectedFilters
值数组和filters
属性值数组。然后在every
上使用selectedFilters
,检查其中的所有值是否都存在于filters
中。
const selectedFilters = {
color: ["Red", "Blue"],
type: ["Shirt"],
size: ["M"]
};
const items = [
{
name: "Item 1",
filters: {
color: ["Red", "Blue", "Black"],
type: ["Shirt"],
size: ["M"]
}
},
{
name: "Item 2",
filters: {
color: ["Red"],
type: ["Pants"],
size: ["M"]
}
}
];
const filterArr = Object.values(selectedFilters).flat();
const output = items.filter(({filters}) => {
const objFilters = Object.values(filters).flat();
return filterArr.every(val => objFilters.includes(val));
})
console.log(output);
答案 1 :(得分:0)
您可以使用some
检查数组中是否包含至少一个元素,并且该函数期望布尔返回值。
some()
方法测试数组中是否至少有一个元素 通过提供的功能实现的测试。它返回一个 布尔值。
const selectedFilters = {"color":["Red","Blue"],"type":["Shirt"],"size":["M"]}
const items = [{"name":"Item 1","filters":{"color":["Red","Blue","Black"],"type":["Shirt"],"size":["M"]}},{"name":"Item 2","filters":{"color":["Red"],"type":["Pants"],"size":["M"]}}]
const filterItems = (items, selectedFilters) => {
const filterKeys = Object.keys(selectedFilters);
return items.filter(item => {
return filterKeys.every(key => {
return selectedFilters[key].some(filterWord => { //Use some
return item.filters[key].includes(filterWord); //Return the a bool
});
})
});
};
var result = filterItems(items, selectedFilters);
console.log(result);
更短版本:
const selectedFilters = {"color":["Red","Blue"],"type":["Shirt"],"size":["M"]};
const items = [{"name":"Item 1","filters":{"color":["Red","Blue","Black"],"type":["Shirt"],"size":["M"]}},{"name":"Item 2","filters":{"color":["Red"],"type":["Pants"],"size":["M"]}}];
const filterItems = (items, selectedFilters) => {
const fkeys = Object.keys(selectedFilters);
return items.filter(i => fkeys.every(k => selectedFilters[k].some(o => i.filters[k].includes(o))));
};
const result = filterItems(items, selectedFilters);
console.log(result);
答案 2 :(得分:0)
您可以为此使用Array.filter()函数。这是解决这个问题的非常简单有效的方法。
Array.prototype.diff = function(arr2) {
var ret = [];
for(var i in this) {
if(arr2.indexOf(this[i]) > -1){
ret.push(this[i]);
}
}
return ret;
};
var filteredArr = items.filter(function (el) {
return el.filters.color.diff(selectedFilters.color).length > 0 &&
el.filters.type.diff(selectedFilters.type).length > 0 &&
el.filters.size.diff(selectedFilters.size).length > 0
});
这是工作示例。
https://playcode.io/325371?tabs=console&script.js&output
注意: ,您可以根据自己的要求更改AND / OR条件。
答案 3 :(得分:0)
有很多方法可以解决此问题。例如,您的解决方案是正确的,但是我们需要像这样在每个回调中移除卷曲的{}
:
filterWord => item.filters[key].includes(filterWord)
另一种选择是使用selectedFilters
方法将filterValues
转换为flat()
数组。此方法创建一个新数组,其中所有子数组元素都以递归方式连接到该数组中。现在,我们提取每个filters
的{{1}}并再次使用items
方法将其转换为itemFilters
数组。然后,我们尝试将它们与结合了flat()
和filterValues
方法的every()
进行匹配。两者都将测试数组中的所有元素是否包括每个includes()
的元素。
第三个选项与您的解决方案非常相似。在这种情况下,我们将filter
键提取到selectedFilters
数组中。然后,对于每个types
,我们将type
方法与some()
方法结合使用以测试includes()
中是否包含数组中的至少一个元素。
这里有实现:
items.filters[type]
答案 4 :(得分:0)
500,9736,264
1000,9472,528
1500,9197,803
2000,8913,1087
2500,8611,1389
3000,8292,1708
3500,7968,2032
4000,7643,2357
4500,7312,2688
5000,6960,3040
5500,6613,3387
6000,6257,3743
6500,5913,4087
7000,5570,4430
7500,5212,4788