Mint_Sauce
Mint_Sauce

Reputation: 55

Remove deep items from an object

I'm looking to remove the encapsulating object that recipeStep resides in that's equal to heat. So the first array items in recipeMealSteps would be removed as it contains heat.

I've tried using .map and .filter, but I'm not getting back the whole object minus the heat steps.

Here's what I've got so far that's failing:

let filteredRecipes = meals.map((m) =>
  m.mealTypeRecipes.map((r) => r.recipeMealSteps.filter((s) => s.recipeStep !== 'heat'))
);

let meals = [
  {
    mealId: 0,
    mealDescription: "Favourties",
    mealTypeRecipes: [
      {
        recipeAuthor: "Frank Doe",
        recipeDescription: "Great chicken dish for those that don't eat chicken",
        recipeID: 0,
        recipeMealSteps: [
          {
            recipeDesc: "Heat up the oven",
            recipeStep: "heat",
          },
          {
            recipeDesc: "Allow it to cook",
            recipeStep: "cool",
          },
          {
            recipeDesc: "Take it out the oven",
            recipeStep: "out",
          },
        ],
      },
      {
        recipeID: 1,
        recipeName: "Fish Dish",
        recipeMealSteps: [
          {
            recipeDesc: "Heat up the oven",
            recipeStep: "heat",
          },
          {
            recipeDesc: "Allow it to cook",
            recipeStep: "cool",
          },
          {
            recipeDesc: "Take it out the oven",
            recipeStep: "out",
          },
        ],
      },
    ],
  },
];

Upvotes: 0

Views: 74

Answers (1)

de3
de3

Reputation: 2000

let filteredRecipes = meals.map(({mealTypeRecipes, ...m}) => ({
  ...m,
   mealTypeRecipes: mealTypeRecipes.map(({recipeMealSteps,...r}) => ({
     ...r, 
     recipeMealSteps: recipeMealSteps.filter((s) => s.recipeStep !== 'heat') 
    })
)}));

EDIT:

Explanation: in the first map, we get as a parameter of the callback function every meal item. We deconstruct it so that 'm' is an object with all properties 'mealTypeRecipes' (in this case, m has properties 'meadId' and 'mealDescription'). On the other hand we put in the variable 'mealTypeRecipes' the value of the property 'mealTypeRecipes'. This is done thanks to the spread operator "...". This would be equivalent

let filteredRecipes = meals.map((mealItem) => {
    const {mealTypeRecipes, ...m} = mealItem 

Then we return the reconstructed object returning the new value for property "mealTypeRecipes" and putting it together we the part of the object we didn't modify, "...m". This creates a copy of the old object, ensuring immutability.

A more verbose way to do the same would be like this

let filteredRecipes = meals.map((meal) => {
  const {mealTypeRecipes, ...m} = meal;
  return {
    ...m,
     mealTypeRecipes: mealTypeRecipes.map((mealTypeRecipeItem) => {
       const {recipeMealSteps,...r} = mealTypeRecipeItem;
       return {
          ...r,
          recipeMealSteps: recipeMealSteps.filter((s) => s.recipeStep !== 'heat')    
       }
     })
    }
 });

Upvotes: 2

Related Questions