0

This is what I have so far and what I've and tried:

groceryList = [];

ngOnInit() {
  this._recipesSub = this.recipesService.recipes.subscribe((receivedData) => {
    this.loadedRecipes = receivedData.recipes;
  });
}
onCheckRecipe(e) {
    if (e.detail.checked === true) {
      let tickedRecipe = e.detail.value;
      let selectedRecipeIngredients;
      for (let recipe of this.loadedRecipes) {
        if (recipe.name === tickedRecipe) {
          selectedRecipeIngredients = recipe.ingredients;
        }
      }
      for (let selectedIng of selectedRecipeIngredients) {
        for (let existingIng of this.groceryList) {
          if (selectedIng.name) {
            this.groceryList.push(selectedIng);
          }
        }
      }
      console.log(this.groceryList);
    }
  }

This is what I receive in my console:

(8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {_id: "5f64ac1eb227fea1f63a5c99", name: "chia seeds", quantity: "10g"}
1: {_id: "5f64ac1eb227fea1f63a5c9a", name: "cherries", quantity: "15g"}
2: {_id: "5f64ac1eb227fea1f63a5c9b", name: "honey", quantity: "30g"}
3: {_id: "5f64ac1eb227fea1f63a5c9c", name: "almond flour", quantity: "10g"}
4: {_id: "5f64ac1eb227fea1f63a5c9e", name: "almond flour", quantity: "10g"}
5: {_id: "5f64ac1eb227fea1f63a5c9f", name: "egg", quantity: "10g"}
6: {_id: "5f64ac1eb227fea1f63a5ca0", name: "unsalted butter", quantity: "30g"}
7: {_id: "5f64ac1eb227fea1f63a5ca1", name: "peanut butter", quantity: "50g"}
length: 8
__proto__: Array(0)

and my desire outcome is not to have name: "almond flour" twice because it was already in the array, so i can be able to add just the object that which name value doesn't exist already:

Instead of 3: {_id: "5f64ac1eb227fea1f63a5c9c", name: "almond flour", quantity: "10g"}, {_id: "5f64ac1eb227fea1f63a5c9e", name: "almond flour", quantity: "10g"} to be {_id: "5f64ac1eb227fea1f63a5c9e", name: "almond flour", quantity: "20g"}

What I want to achieve is to add to my groceryList array each Ingredient only if that ingredient is not present already and if it's present to add just the quantity of that ingredient to an existing key. For example if i have the ingredient {_id: "5f64ac1eb227fea1f63a5c99", name: "chia seeds", quantity: "10g"} to add just the quantity and not to create a new obj of ingredient in my groceryList

I am don't know what approach to take.. If you guys have any idea I would really appreciate it.

** Also the remove option

onCheckRecipe(e) {
    if (e.detail.checked === true) {
      for (let recipe of this.loadedRecipes) {
        if (recipe.name === e.detail.value) {
          recipe.ingredients.forEach((eachIngredient) => {
            let matchedIng = this.groceryList.find(function (foundIng) {
              return foundIng.name === eachIngredient.name;
            });
            if (matchedIng) {
              matchedIng.quantity =
                matchedIng.quantity + eachIngredient.quantity;
            } else {
              this.groceryList.push(eachIngredient);
            }
          });
        }
      }
    } else {
      for (let recipe of this.loadedRecipes) {
        if (recipe.name === e.detail.value) {
          recipe.ingredients.forEach((element) => {
            let matched = this.groceryList.find(function (foundIngre) {
              return foundIngre.name === element.name;
            });
            if (matched.quantity === element.quantity) {
              let index = this.groceryList.findIndex(
                (x) => x.name === matched.name
              );
              this.groceryList.splice(index, 1);
            } else {
              matched.quantity = matched.quantity - element.quantity;
            }
          });
        }
      }
    }
  }
4
  • Please provide some sample input data and expected results. Also what errors are you receiving? What is going wrong? You provided a bunch of code with no real technical problem statement or where specifically in that code you are having issues Commented Sep 18, 2020 at 20:58
  • Hi @charlietfl, apologise. I just added a little bit more information and the desired outcome. Thank you for the heads up! Commented Sep 18, 2020 at 21:03
  • So what should result be...change qty to "20g"? Shouldn't all id for "almond flour" be the same? Commented Sep 18, 2020 at 21:06
  • yes, and to keep just one obj with name: "almond flour" . Instead of 3: {_id: "5f64ac1eb227fea1f63a5c9c", name: "almond flour", quantity: "10g"} 4: {_id: "5f64ac1eb227fea1f63a5c9e", name: "almond flour", quantity: "10g"} to be 4: {_id: "5f64ac1eb227fea1f63a5c9e", name: "almond flour", quantity: "20g"} Commented Sep 18, 2020 at 21:08

2 Answers 2

1

Loop over the ingredients array and use Array.prototype.find() to look for a match for each iteration. If one exists, update quantity, otherwise push ingredient object to the array

One suggestion to simplify the computation would be add another field for the units and store quantity as a number so you don't need to parse units from a string just to do the simple math

const ingredients = [{_id: "5f64ac1eb227fea1f63a5c9e", name: "almond flour", quantity: "10g"}];

ingredients.forEach(ingr => {
   // returns matching object or undefined
   const wanted = data.find(({_id}) => _id === ingr._id);
   if(wanted){
     const {quantity: wq} = wanted,
           units = wq.match(/\D+/)[0];      
     wanted.quantity = parseInt(wq) + parseInt(ingr.quantity) + units;  
   }else{
     data.push(obj)
   }
})
 console.log(data)
.as-console-wrapper {max-height: 100%!important;top:0;}
<script>
const data =  [{_id: "5f64ac1eb227fea1f63a5c99", name: "chia seeds", quantity: "10g"},
 {_id: "5f64ac1eb227fea1f63a5c9a", name: "cherries", quantity: "15g"},
 {_id: "5f64ac1eb227fea1f63a5c9b", name: "honey", quantity: "30g"},
 {_id: "5f64ac1eb227fea1f63a5c9e", name: "almond flour", quantity: "10g"},
 
 {_id: "5f64ac1eb227fea1f63a5c9f", name: "egg", quantity: "10g"},
 {_id: "5f64ac1eb227fea1f63a5ca0", name: "unsalted butter", quantity: "30g"},
 {_id: "5f64ac1eb227fea1f63a5ca1", name: "peanut butter", quantity: "50g"}]
</script>

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

3 Comments

Hi! Thank you so much.. I am trying to understand your code as it's syntax that I've never used, just started learning coding and trying to figure it out how can i adapt it to my approach as I don't want to just copy code and to not understand it
Try this version that doesn't use ES6 features like arrow functions and destructuring pastiebin.com/5f652e811470a
Hi! Sorry, to bother you but do you have any idea how I can do the opposite? I mean to subtract the value or to remove it? I've been trying for a few days but with no results... I also edited my post with what I've tried maybe you have an idea of how to approach it
1

This is my Solution, i hope that is helpful :

const data = [
  { _id: "5f64ac1eb227fea1f63a5c99", name: "chia seeds", quantity: "10g" },
  { _id: "sdf7687hkksjj8881zzaooPP", name: "peanut butter", quantity: "20g" },
  { _id: "abcf781eb227fea1f63a5c9a", name: "cherries", quantity: "15g" },
  { _id: "5f64ac1eb227fea1f63a5c9b", name: "honey", quantity: "30g" },
  { _id: "5f64ac1eb227fea1f63a5c9c", name: "almond flour", quantity: "10g" },
  { _id: "5f64ac1eb227fea1f63a5c9e", name: "almond flour", quantity: "10g" },
  { _id: "5f64ac1eb227fea1f63a5c9f", name: "egg", quantity: "10g" },
  { _id: "ghg990c1eb227fea1f63a5c7", name: "egg", quantity: "19g" },
  { _id: "dsfsdffer340fea1f63a5ca0", name: "unsalted butter", quantity: "30g" },
  { _id: "5f64ac1eb227fea1f63a5ca1", name: "peanut butter", quantity: "50g" }
];

const groceryList = data.reduce(
  (acc, value) => {
    const index = acc.findIndex(elt => elt.name === value.name);
    if (index !== -1) {
      const accQuantity = acc[index].quantity;
      const valueQuantity = value.quantity;
      const unit = accQuantity.match(/\D+/)[0];
      acc[index].quantity = +accQuantity.match(/\d+/)[0] + +valueQuantity.match(/\d+/)[0] + unit;
    } else {
      acc.push(value);
    }
    return acc;
  }, []
);
console.log(groceryList);

Comments

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.