Question: 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: "john.doe@gmail.com",
        citizenship: "US",
        country: "US",
        state: "GA",
    }

```

and I'm trying to create a function that can filter data by phone, email, name(first and last), country, state, and id. However, all 7 fields may, or may not, be filtered 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.

**ANSWER - this is based on the correct answer i marked below but his code is slightly flawed.**

```
const filterParams = {
        firstName: fname,
        lastName: lname,
        phone: phone,
        email: email,
        country: country,
        state: state,
    };

const search = (objArray, filterParams) => {
    return objArray.filter((obj) => {
        return Object.keys(filterParams).every((key) =>
                obj[key].toLowerCase().includes(filterParams[key].toLowerCase())
            );
        });
    };

```

Answer: 
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]); 
    });
};

```
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: "john.doe@gmail.com",
    citizenship: "US",
    country: "US",
    state: "GA"
  }
];

//3. Have fun combining them...
console.log(and([eqStrictFirstName("john"), hasPhone('21')], array));

```