I've written a small application that has an array of recipes. Each recipe then has a child array of ingredients. What I would like to do is iterate through all of the ingredients in all of the recipes and pull out the unique ingredients.
At the moment I have a function that iterates through all ingredients, from all recipes, and then adds an empty version of that ingredient to the set. This should work but when I log the result, it doesn't make sense because ingredients added to the set are all populated - they're not using the empty objects that I created. Because of the nested properties being different, this means the set is adding the ingredient multiple times because the objects aren't equal.
I was then re-looping through the ingredients afterwards to calculate the values, but this should only be happening after the logger entry. So I don't understand how the values are being populated before that functionality is called?
This is what I have currently:
calculate(recipes: Recipe[]): Observable<Calculation[]> {
let calculations: Calculation[] = [];
let uniqueIngredients = new Set();
for (let i = 0; i < recipes.length; i++) {
for (let j = 0; j < recipes[i].ingredients.length; j++) {
// First get all the unique ingredients
uniqueIngredients.add(this.getEmptyIngredient(recipes[i].ingredients[j]));
}
}
console.log('unique ingredients', uniqueIngredients);
let $this = this;
uniqueIngredients.forEach(function (value) {
let ingredientCalculation = value as Calculation;
for (let i = 0; i < recipes.length; i++) {
for (let j = 0; j < recipes[i].ingredients.length; j++) {
if (ingredientCalculation.ingredient.definition.name === recipes[i].ingredients[j].definition.name) {
// Calculation already exists so update it
let calculation: Calculation = $this.calculateIngredient(recipes[i].ingredients[j], recipes[i].quantity);
ingredientCalculation.quantityMeasurement += calculation.quantityMeasurement;
ingredientCalculation.quantityUnits += calculation.quantityUnits;
ingredientCalculation.totalCost += calculation.totalCost;
}
}
}
calculations.push(ingredientCalculation);
});
return of(calculations);
}
private getEmptyIngredient(ingredient: Ingredient): Calculation {
let calculation: Calculation = {
ingredient: ingredient,
quantityUnits: 0,
quantityMeasurement: 0,
totalCost: 0
};
return calculation;
}
When I look at the console, this is the result:
Judging by my code, I would have expected there to be only 1 instance of 'Apple' with all the properties set to 0, but this isn't the case.
Could anyone explain to me where I'm going wrong?
EDIT: I understand the comments about object equality, but what I don't understand is that the objects should be empty: At the time the console logs, the collect should contain empty objects - why are they all populated at that point when all of the calculation logic happens after the log?