Adib Sadeghi
Adib Sadeghi

Reputation: 128

Filter array of object based on multiple conditions in React

I wanna filter person list according to city job age gender how can I filter based on five conditions in react, I used filter chaning but it did not work for me .in useEffect hook I filter individual condition and then i used chaning filter but it seems I should respectively filtered

briefly i wanna filtered persons according to five conditions to handle this scenario I used useEffect hook and I used filter method to each condition but I don't know how they can work together

  const [persons, setPersons] = useState([
    {
      id: 1,
      name: "mosh",
      gender: "0",
      city: "London",
      category: "frontend",
      age: 27,
    },
    {
      id: 2,
      name: "saheb",
      gender: "1",
      city: "Paris",
      category: "backend",
      age: 32,
    },
    {
      id: 3,
      name: "vahid",
      gender: "0",
      city: "Rome",
      category: "frontend",
      age: 43,
    },
    {
      id: 4,
      name: "kianosh",
      gender: "1",
      city: "London",
      category: "designer",
      age: 29,
    },
    {
      id: 5,
      name: "milad",
      gender: "0",
      city: "Paris",
      category: "designer",
      age: 41,
    },
    {
      id: 6,
      name: "parviz",
      gender: "1",
      city: "Rome",
      category: "designer",
      age: 56,
    },
    {
      id: 7,
      name: "farid",
      gender: "0",
      city: "London",
      category: "frontend",
      age: 37,
    },
    {
      id: 8,
      name: "rezgar",
      gender: "1",
      city: "Rome",
      category: "backend",
      age: 29,
    },
    {
      id: 9,
      name: "ali",
      gender: "0",
      city: "Paris",
      category: "backend",
      age: 48,
    },
  ]);
  const [filteredPersons, setFilteredPersons] = useState([]);
  const [checkedValue, setCheckedValue] = useState([]);
  const [select, setSelect] = useState("all");
  const [gender, setGender] = useState("");
  const [range, setRange] = useState(100);
  const [max, setMax] = useState(null);
  const [search, setSearch] = useState("");

  useEffect(() => {
    const maximum = Math.max(...persons.map((item) => item.age));
    setMax(maximum);
  }, []);

  useEffect(() => {
    console.log("useeffect runs");
    const oldPersons = [...persons];
    const filteredCity = (person) => {
      if (checkedValue.includes(person.city)) {
        return person;
      }
      return null;
    };
    const filteredAge = (person) => {
      return person.age < range;
    };
    const filteredGender = (person) => {
      return person.gender == gender;
    };
    const filteredSelect = (person) => {
      if (select === "all") {
        return person;
      } else {
        return person.category == select;
      }
    };

    const filteredAllPersons = oldPersons
      .filter(filteredGender)
      .filter(filteredAge)
      .filter(filteredSelect)
      ?.filter(filteredCity)
    setFilteredPersons(filteredAllPersons);
  }, [checkedValue, select, gender, range, search]);

Upvotes: 5

Views: 16443

Answers (2)

Javad Masoudian
Javad Masoudian

Reputation: 62

You can only handle it through one filter() method

useEffect(() => {
    const oldPersons = [...persons];

    const filteredAllPersons = oldPersons.filter(person => {
        if(!checkedValue.includes(person.city)) return false;

        if(person.age >= range) return false;

        if(person.gender !== gender) return false;

        if (select === "all") return person;

        return person.category === select;
    })

    setFilteredPersons(filteredAllPersons);
}, [persons, checkedValue, select, gender, range]);

in return

return filteredPersons.length > 0 && <div>{console.log(filteredPersons)}</div>

Upvotes: 3

Mario Nikolaus
Mario Nikolaus

Reputation: 2406

The issue is that you are applying all of your filters instead of just ones that are defined. And also you also should just return false from your filters if they are defined, that is the only way to run through all of them. So your code should look something like this

const filteredAllPersons = oldPersons.filter(person => {
  if (genderFilter && person.gender !== genderFilter) {
    return false
  }
  // apply all other filters the same as above

  // Finally return true because record has satisfied all conditions
  return true
})

Upvotes: 5

Related Questions