So I'm having a hard time figuring out the best way to search by 1, or up to 7, different values. My data looks like this
{
id: "123456",
firstName: "john",
lastName: "doe",
middleName: "Leon",
phone: "3216549878",
dob: "10/12/1984",
prefix: "Mr",
suffix: "",
gender: "male",
ageClass: "adult",
email: "[email protected]",
citizenship: "US",
country: "US",
state: "GA",
}
and I'm trying to create a function that can search by either phone, email, name(first and last), country, state, and id. However, all 7 fields may, or may not, be searched at the same. For example, the user may want to search by phone and name, strictly just phone number, or only by email, or search by all 7 criteria.
I created the function but it's a 260-line if statement that is extremely hard to read and looks like a god-awful mess and that is why I'm trying to find a better way to do this.
CodePudding user response:
You can send an object with key value pair based on which you want to filter. For example if you want to filter entries that have first name Chris and last name Doe:
// filterParams = {firstName:"Chris", "lastName":"Doe"}
const search = (objArray, filterParams) => {
return objArray.filter(obj => {
Object.keys(searchParams).every(key => searchParams[key] === obj[key]);
});
};
CodePudding user response:
In order to make it fast and generic at the same time you should have only one loop over the array and have generic filter functions for your object.
There is a beautiful way to express is declaratively with functional programming.
import filter from "lodash/fp/filter";
import curry from 'lodash/fp/curry';
//1. Create generic filter function for your object schema
const eqStrictFirstName = (name) => filter((x) => x.firstName === name);
const hasPhone = (num) => filter(x => x.phone.includes(num));
//2. Make a generic function to combine those functions
//according to your business logic
const and = curry((predicates, item) => {
return predicates.reduce((hasPassedSoFar, predicate) => hasPassedSoFar && predicate(item), true);
});
const array = [
{
id: "123456",
firstName: "john",
lastName: "doe",
middleName: "Leon",
phone: "3216549878",
dob: "10/12/1984",
prefix: "Mr",
suffix: "",
gender: "male",
ageClass: "adult",
email: "[email protected]",
citizenship: "US",
country: "US",
state: "GA"
}
];
//3. Have fun combining them...
console.log(and([eqStrictFirstName("john"), hasPhone('21')], array));