在Javascript中过滤多个数组对象并将键值与多个值匹配形成另一个数组
Filter multiple Array Objects and match key values with multiple values form another array in Javascript
我已经绞尽脑汁几个晚上了,我希望好心人能帮助解决我遇到的这堵墙。
我有一个对象数组。
作为用户,我应该能够通过多个或单个过滤器来过滤功能名称。
单个过滤器应 return 所有具有匹配名称的事件
多重过滤器应匹配具有多个特征名称的所有事件,不少于 2 或过滤器数组的长度。
我最终坚持使用的代码或者我能做到的就是这个。
let obj1 = [{
"results": [{
"id": "1",
"name": "Event 1",
"feature": [{
"id": {
"target": "78"
},
"name": "Bronze"
},
{
"id": {
"target": "27"
},
"name": "Straw"
},
{
"id": {
"target": "45"
},
"name": "Gold"
}
]
},
{
"id": "2",
"name": "Event 2",
"feature": [{
"id": {
"target": "20"
},
"name": "Straw"
}]
},
{
"id": "3",
"name": "Event 3",
"feature": [{
"id": {
"target": "20"
},
"name": "Gold"
},
{
"id": {
"target": "20"
},
"name": "Straw"
}
]
},
{
"id": "4",
"name": "Event 4",
"feature": [{
"id": {
"target": "97"
},
"name": "Coal"
},
{
"id": {
"target": "39"
},
"name": "Wood"
}
]
}
]
}]
let filterQuery = ['Straw', 'Gold'];
obj1 = obj1[0].results.filter(r => {
return r.feature.every(f => {
return filterQuery.includes(f.name)
})
})
console.log(obj1);
它用 Straw
或 Gold
过滤任何东西,用稻草和金
过滤所有东西
我正在尝试让过滤器过滤 Straw && Gold
所以return用例子
{name: 'Straw', name: 'Gold', name: 'Diamond', name: Copper}
将是一个正确的匹配项,因此用户可以向数组添加另一个过滤器以进一步过滤结果。
{ name: Straw, name: Diamond }
匹配不正确。
任何帮助,建议将不胜感激:)
============================================= ==============
已更新解决方案。我需要它尽可能不可知,以便在键名更改时它能正常工作。用于 Drupal 的 Vuejs 项目。
export default class FilterData {
constructor(name, data, filter_query) {
this.name = name;
this.data = data;
this.filter_query = filter_query;
}
filterData(){
let temp = this.data
// filter out any undefined arrays
temp = temp.filter((item) => item[this.name] !== undefined);
temp = temp.filter((item) =>
[this.filter_query].every((filter) =>
item[this.name].some(({ name }) => name === filter)
)
);
return temp
}
}
然后像这样使用它
/* use a temp copy of the returned data from the api
so we can keep refiltering from multiple drop downs, radio, checkboxes changes each time a filter keyname is un-selected.
*/
let apiResults = this.apiData.results;
let filtered = new FilterData(
`${keyname}`,
apiResults,
this.filterQuery[`${keyname}`]
);
非常感谢@pilchard,您的回答对此有很大帮助。
您需要将 every()
调用切换到 filterQuery
数组。因此,测试过滤器数组中的 every()
字符串是否在 feature
数组中有匹配项,这里使用 some()
.
进行测试
let obj1 = [{ "results": [{ "id": "1", "name": "Event 1", "feature": [{ "id": { "target": "78" }, "name": "Bronze" }, { "id": { "target": "27" }, "name": "Straw" }, { "id": { "target": "45" }, "name": "Gold" }] }, { "id": "2", "name": "Event 2", "feature": [{ "id": { "target": "20" }, "name": "Straw" }] }, { "id": "3", "name": "Event 3", "feature": [{ "id": { "target": "20" }, "name": "Gold" }, { "id": { "target": "20" }, "name": "Straw" }] }, { "id": "4", "name": "Event 4", "feature": [{ "id": { "target": "97" }, "name": "Coal" }, { "id": { "target": "39" }, "name": "Wood" }] }] }]
let filterQuery = ['Straw', 'Gold'];
const filteredObj = obj1[0].results.filter(({ feature }) =>
filterQuery.every(filter =>
feature.some(({ name }) => name === filter)))
console.log(filteredObj);
我已经绞尽脑汁几个晚上了,我希望好心人能帮助解决我遇到的这堵墙。
我有一个对象数组。
作为用户,我应该能够通过多个或单个过滤器来过滤功能名称。 单个过滤器应 return 所有具有匹配名称的事件 多重过滤器应匹配具有多个特征名称的所有事件,不少于 2 或过滤器数组的长度。
我最终坚持使用的代码或者我能做到的就是这个。
let obj1 = [{
"results": [{
"id": "1",
"name": "Event 1",
"feature": [{
"id": {
"target": "78"
},
"name": "Bronze"
},
{
"id": {
"target": "27"
},
"name": "Straw"
},
{
"id": {
"target": "45"
},
"name": "Gold"
}
]
},
{
"id": "2",
"name": "Event 2",
"feature": [{
"id": {
"target": "20"
},
"name": "Straw"
}]
},
{
"id": "3",
"name": "Event 3",
"feature": [{
"id": {
"target": "20"
},
"name": "Gold"
},
{
"id": {
"target": "20"
},
"name": "Straw"
}
]
},
{
"id": "4",
"name": "Event 4",
"feature": [{
"id": {
"target": "97"
},
"name": "Coal"
},
{
"id": {
"target": "39"
},
"name": "Wood"
}
]
}
]
}]
let filterQuery = ['Straw', 'Gold'];
obj1 = obj1[0].results.filter(r => {
return r.feature.every(f => {
return filterQuery.includes(f.name)
})
})
console.log(obj1);
它用 Straw
或 Gold
过滤任何东西,用稻草和金
我正在尝试让过滤器过滤 Straw && Gold
所以return用例子
{name: 'Straw', name: 'Gold', name: 'Diamond', name: Copper}
将是一个正确的匹配项,因此用户可以向数组添加另一个过滤器以进一步过滤结果。
{ name: Straw, name: Diamond }
匹配不正确。
任何帮助,建议将不胜感激:)
============================================= ==============
已更新解决方案。我需要它尽可能不可知,以便在键名更改时它能正常工作。用于 Drupal 的 Vuejs 项目。
export default class FilterData {
constructor(name, data, filter_query) {
this.name = name;
this.data = data;
this.filter_query = filter_query;
}
filterData(){
let temp = this.data
// filter out any undefined arrays
temp = temp.filter((item) => item[this.name] !== undefined);
temp = temp.filter((item) =>
[this.filter_query].every((filter) =>
item[this.name].some(({ name }) => name === filter)
)
);
return temp
}
}
然后像这样使用它
/* use a temp copy of the returned data from the api
so we can keep refiltering from multiple drop downs, radio, checkboxes changes each time a filter keyname is un-selected.
*/
let apiResults = this.apiData.results;
let filtered = new FilterData(
`${keyname}`,
apiResults,
this.filterQuery[`${keyname}`]
);
非常感谢@pilchard,您的回答对此有很大帮助。
您需要将 every()
调用切换到 filterQuery
数组。因此,测试过滤器数组中的 every()
字符串是否在 feature
数组中有匹配项,这里使用 some()
.
let obj1 = [{ "results": [{ "id": "1", "name": "Event 1", "feature": [{ "id": { "target": "78" }, "name": "Bronze" }, { "id": { "target": "27" }, "name": "Straw" }, { "id": { "target": "45" }, "name": "Gold" }] }, { "id": "2", "name": "Event 2", "feature": [{ "id": { "target": "20" }, "name": "Straw" }] }, { "id": "3", "name": "Event 3", "feature": [{ "id": { "target": "20" }, "name": "Gold" }, { "id": { "target": "20" }, "name": "Straw" }] }, { "id": "4", "name": "Event 4", "feature": [{ "id": { "target": "97" }, "name": "Coal" }, { "id": { "target": "39" }, "name": "Wood" }] }] }]
let filterQuery = ['Straw', 'Gold'];
const filteredObj = obj1[0].results.filter(({ feature }) =>
filterQuery.every(filter =>
feature.some(({ name }) => name === filter)))
console.log(filteredObj);