Hi all,
I have a challenge to solve where I am building a filter component that can filter data across multiple categories and return unique results. Functionality wise, it’s pretty much like what you see on eCommerce websites.
Currently, I have gotten to the point where I can filter items across categories using an OR condition but I need to build an AND condition across categories.
So, the data I am working with are called “services”. Here is how I have organised the data (each time a filter item is checked, it gets pushed into this object
So, now I’m wondering how I can find an intersection / union (I’m not sure what algorithm I need) across all services in order to find service/s that match ALL categories.
For example, given the screenshot above, a service item would need:
Type === Licence
Topic === 'Supplying Government' || 'Privacy'
Level === 'Local'
Agency === 'Australian Taxation Office' || 'Chief Health Office Branch'
This is a typical data object that I need to work with(called a service).
{
"__typename": "Service",
"Id": 26,
"Jurisdiction": "AG",
"ServiceType": "Licence",
"TierOfGovernment": "Commonwealth",
"Name": "Australian Business Number Registration",
"DescriptiveName": "Australian Business Number (ABN) Registration",
"ServiceTopics": [
{
"__typename": "ServiceTopic",
"TopicId": 52,
"TopicName": "General Taxation Requirements and Registrations"
}
],
"ServiceOrganisations": [
{
"__typename": "ServiceOrganisation",
"Id": 387618,
"ServiceId": 26,
"OrganisationName": "Australian Taxation Office",
"Sequence": 10,
"Group": "1"
},
{
"__typename": "ServiceOrganisation",
"Id": 387619,
"ServiceId": 26,
"OrganisationName": "Australian Business Register",
"Sequence": 20,
"Group": "1"
}
]
}
Here is the component UI (just for clarity):
Thank you for any help or direction in advance! Would an intersection / union algorithm be appropriate? And how can I build a dynamic filter function across multiple data points?
I tried looking into JSON Path (https://github.com/JSONPath-Plus/JSONPath) but I’m not sure exactly how to best use it. Here is how I do the lazy filter function:
const lazyFilterMatch = services.filter((service: Service) => {
return filters.some((filter: ServiceFilterItem) => {
// search deep in an object to get it's value
const values = JSONPath({ path: filter.serviceSearcher, json: service });
const valueMatch = values.includes(filter.searchTerm);
// check the filters against the config to get the correct serviceSearcher path
const filterLabelMatch = resultFilterConfig.find(
(item) => item.serviceSearcher === filter.serviceSearcher,
);
// build an object to organise data & intersect / union results later
if (!categories[filterLabelMatch.filterLabel][filter.searchTerm]) {
categories[filterLabelMatch.filterLabel][filter.searchTerm] = [];
} else if (valueMatch) {
categories[filterLabelMatch.filterLabel].searchPath = filter.serviceSearcher;
categories[filterLabelMatch.filterLabel][filter.searchTerm].push(service);
return valueMatch;
}
return false;
});
});
Any help or direction would be GREATLY appreciated! Thank you!