skip to Main Content

I was wondering how to use filter() on an array of objects like this one:

const tattoos = [
  {
    head: [
      {
        name: "1 - Crâne de pirate (H/F)",
        gender: "HF",
        price: "450",

      },
      {
        name: "2 - Surf LS (H/F)",
        gender: "HF",
        price: "250",
      },
      {
        // etc...
      },
    ],
    torso: [
      {
        name: "1 - Crâne de pirate (H/F)",
        gender: "HF",
        price: "450",

      },
      {
        name: "2 - Surf LS (H/F)",
        gender: "HF",
        price: "250",
      },
      {
        // etc...
      },
    ],

I want to use it in this React Component:

// SIMPLE VERSION FOR EASIER UNDERSTANDING

import React, { useState, useEffect } from "react";

const tattoos = [{...}]

export default function Searchbar() {
  const [filtered, setFiltered] = useState([]);
  const [bodypart, setBodypart] = useState("all");

  function handleChange(e) {
    setBodypart(e.target.value);
  }

  useEffect(() => {
    if (bodypart === "all") {
      setFiltered(tattoos);
      return;
    }

    const filtered = tattoos.filter( // This is where I'm stuck )
    setFiltered(filtered);
  }, []);
  return (
    <div>
        <div>
          <label>
            Bodypart:
          </label>
          <select onChange={handleChange}>
            <option value="all">All</option>
            <option value="head">Head</option>
            <option value="torso">Torso</option>
          </select>
        </div>
    </div>
  );
}

Expected behavior:

  • Click on an option
  • Store the value in "bodypart" state
  • Use filter() on the main array and filter using "bodypart" state

I already tried:

const filtered = tattoos.filter(e => e === bodypart)
const filtered = tattoos.filter(e => e.includes(bodypart))
const filtered = tattoos.filter(e => e.some(bodypart))
const filtered = tattoos.filter(e => Objects.keys(e).includes(bodypart))

But I always ended with an empty array or an error.

Thanks for your help!

2

Answers


  1. The tattoos array seems to consist of just 1 object, or at least you don’t show any more than 1 item. If that is indeed all it contains, then you can take tattoos[0] and then access the needed property using [bodypart].

    const tattoos = [
      {
        head: [
          { name: "1 - Crâne de pirate (H/F)", gender: "HF", price: "450" },
          { name: "2 - Surf LS (H/F)", gender: "HF", price: "250" },
        ],
        torso: [
          { name: "1 - Crâne de pirate (H/F)", gender: "HF", price: "450" },
          { name: "2 - Surf LS (H/F)", gender: "HF", price: "250" },
        ],
      }
    ];
    
    const bodypart = "torso";
    const filtered = tattoos[0][bodypart];
    console.log(filtered);
    Login or Signup to reply.
  2. As mentioned in Peter’s answer, your array is containing an object so either make tattoos an object or use tattoos[0], in both cases you will have to deal with an object so follow his solution.


    if tattoos is an array and can contain multiples objects similar to the first one you can do this to get them all from each object :

    const filtered = tattoos.map((tatto) => tatto[bodypart]).filter((bodypart) => bodypart.length);
    

    the .filter returns the whole object, you need only the property "bodypart" that’s why .map is used, then we want to filter and return only non-empty arrays.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search