-1

I have a data set of recipes that I am trying to filter based on an array of inputs.

const [cuisineInput, setCuisineInput] = useState("");
const [cuisineFilter, setCusineFilter] = useState<Filter[]>([]);
const [filteredResults, setFilteredResults] = useState<any>(null);

const filterDataByCuisine = useCallback(() => {
  if (cuisineFilter !== null) {
    const filteredData = data!.hits.filter(({ recipe }: any) => {
      return Object.values(recipe.cuisineType)
      .join("")
      .includes(Object.values(
        cuisineFilter.map((el) => {return el.label;}))
        .join("")
        .toLowerCase()
      );
    });
    setFilteredResults(filteredData);
  }
}, [cuisineFilter, data]);

Here I am setting the filtered data (filteredData) to a new state (filteredResults). I am then mapping over the new data of filtered data to display in the UI. The Issue I am having is I can not filter by multiple input "lables" in the cuisineFilter array. I am mapping over the cuisineFilter array to grab the label because it is an object containing {id: number, label: string} that I am also displaying in the UI. recipe.cuisineType is an array of a single string like ["italian"].

If I only have one "label" in the cuisineFilter array it works fine and filteres the data as expected, but I want to be able to filter by multiple "labels". How can I make the data filter by multiple inputs in the cuisineFilter array?

  • Your code snippet is throwing an error – steev Mar 28 '23 at 18:44
  • Right, because I just provided the function with the logic I has struggling with and not the full react component. – Jack Rackham Mar 28 '23 at 19:17
  • Does this answer your question? [Filter array of objects whose any properties contains a value](https://stackoverflow.com/questions/44312924/filter-array-of-objects-whose-any-properties-contains-a-value) – pilchard Mar 28 '23 at 20:48

1 Answers1

0

I'm not 100% sure I have the data structures right, but does the following help? I think you want to filter to recipes that have a match in their cuisineType array for every label from the filters array.

const recipes = [
  { name: 'Spaghetti bolognese', cuisineType: ['italian', 'pasta', 'tomato'] },
  { name: 'Caramel and pecan gelato', cuisineType: ['italian', 'dessert', 'pecan', 'caramel'] },
  { name: 'Deep fried macaroni cheese pie', cuisineType: ['scottish', 'pasta', 'pie', 'cheese', 'cardiac_failure'] },
  { name: 'Pecan pie', cuisineType: ['american', 'pecan', 'pie'] }
];

const filter_recipes = (recipes, filters) => {
  const filter_terms = filters.map( (filter) => filter.label );
  return recipes.filter(
    (recipe) => filter_terms.every( (term) => recipe.cuisineType.includes(term) )
  );
};

console.log(filter_recipes(recipes, [{ label: 'italian' }]));
console.log(filter_recipes(recipes, [{ label: 'italian' }, { label: 'pasta' }]));
Ben Stephens
  • 3,303
  • 1
  • 4
  • 8