Been racking my head for a few nights now and Im hoping a kind soul can help solve this wall I have hit.
I have an Array of Objects.
As a user I should be able to filter feature name(s) by multiple or singular filters. A single filter should return all events with a matching name A multiple filter should match all events with more than one feature name, not less than 2 or the length of the filters array.
The code I have eventually been stuck with or as far as I can go is this.
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);
It filters anything with Straw or Gold, and everything with Straw and Gold
Im trying to get the filter to filter Straw && Gold
So returning an event(s) with example
{name: 'Straw', name: 'Gold', name: 'Diamond', name: Copper}
would be a correct match, so a user could add another filter to the array to filter the results further.
{ name: Straw, name: Diamond }
Would not be a correct match.
Any help, suggestions would be greatly appreciated :)
===========================================================
Updated, solved solution. I needed it to be agnostic as possible so it works if key names change. Used in a Vuejs project with Drupal.
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
}
}
And use it like so
/* 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}`]
);
Thank you so much @pilchard your answer helped this greatly.
Straw and Goldvs.Straw && Gold