-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?

3
  • Your code snippet is throwing an error Commented Mar 28, 2023 at 18:44
  • Right, because I just provided the function with the logic I has struggling with and not the full react component. Commented Mar 28, 2023 at 19:17
  • Does this answer your question? Filter array of objects whose any properties contains a value Commented Mar 28, 2023 at 20:48

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for taking the time to answer. The .every() method you used lead me in the right direction!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.