Reputation: 25
I Have the following object and I want to sum the values of the same ingredients name, like: tomato: 5, chicken:5, rice: 1, peas: 1, i have this code but is not making the sum, instead is showing all the objects
var data3 = {
"menus": [{
"recipe": "chicken with rice",
"ingredients": [{
"name": "tomato",
"value": 2
}, {
"name": "chicken",
"value": 3
}, {
"name": "rice",
"value": 1
}]
}, {
"recipe": "Garden rice",
"ingredients": [{
"name": "tomato",
"value": 3
}, {
"name": "chicken",
"value": 2
}, {
"name": "peas",
"value": 1
}]
}]
};
var ingredients;
for (var i = 0; i < 10; i++) {
ingredients = data3.menus[i].ingredients;
var temp = {};
var obj = null;
for (var j = 0; j < ingredients.length; j++) {
obj = ingredients[j];
if (!temp[obj.name]) {
temp[obj.name] = obj;
} else {
temp[obj.name].value += obj.value;
}
}
var result = [];
for (var prop in temp)
result.push(temp[prop]);
console.log(result);
};
I will appreciate your help, thanks!
Upvotes: 2
Views: 1839
Reputation: 752
You can create a function that will traverse all ingredients and if ingredient.name
has given name, then add ingredient.value
to your result. Here is ES2015 solution with arrow functions:
const sumIngredients = (menus, name) => {
let result = 0;
menus.forEach(meal => {
meal.ingredients.forEach(ingredient => {
if (ingredient.name === name) {
result += ingredient.value;
}
})
})
return result;
}
The use it:
sumIngredients(data3.menus, 'chicken'); //5
sumIngredients(data3.menus, 'tomato'); //5
sumIngredients(data3.menus, 'rice'); //1
sumIngredients(data3.menus, 'peas'); //1
Working example: https://jsfiddle.net/sc8wrupk/
Upvotes: 0
Reputation: 1515
Your implementation is correct, just you were re-initializing temp again and again. So you just need to take temp out of your for loop.
var data3 = {
"menus": [{
"recipe": "chicken with rice",
"ingredients": [{
"name": "tomato",
"value": 2
}, {
"name": "chicken",
"value": 3
}, {
"name": "rice",
"value": 1
}]
}, {
"recipe": "Garden rice",
"ingredients": [{
"name": "tomato",
"value": 3
}, {
"name": "chicken",
"value": 2
}, {
"name": "peas",
"value": 1
}]
}]
};
var ingredients;
var temp = {};
for (var i = 0; i < data3.menus.length; i++) {
ingredients = data3.menus[i].ingredients;
var obj = null;
for (var j = 0; j < ingredients.length; j++) {
obj = ingredients[j];
if (!temp[obj.name]) {
temp[obj.name] = obj;
} else {
temp[obj.name].value += obj.value;
}
}
};
var result = [];
for (var prop in temp)
result.push(temp[prop]);
console.log(result);
Upvotes: 0
Reputation: 386578
You could use a hash table with the name of the ingredient and use a default value of zero if a property does not exist. Then add the value.
var data3 = { menus: [{ recipe: "chicken with rice", ingredients: [{ name: "tomato", value: 2 }, { name: "chicken", value: 3 }, { name: "rice", value: 1 }] }, { recipe: "Garden rice", ingredients: [{ name: "tomato", value: 3 }, { name: "chicken", value: 2 }, { name: "peas", value: 1 }] }] },
ingredients = Object.create(null);
data3.menus.forEach(function (a) {
a.ingredients.forEach(function (b) {
ingredients[b.name] = (ingredients[b.name] || 0) + b.value;
});
});
console.log(ingredients);
Upvotes: 4