Reputation: 159
[{ingName: "egg", quantity: "2.0", unit: "pcs"},
{ingName: "water", quantity: "0.03", unit: "l"},
{ingName: "salt", quantity: "1.0", unit: "pinch"}],
[{ingName: "egg", quantity: "2.0", unit: "pcs"},
{ingName: "water", quantity: "0.03", unit: "l"},
{ingName: "salt", quantity: "1.0", unit: "pinch"},
{ingName: "olive oil", quantity: "2.0", unit: "tablespoons"]
I have an array structure as above in my app whenever user clicks make pizza or another recipe it adding recipe informations to new menu state given below.
<button
value={item.id}
onClick={(e) => {setMenu([...menu,{name:item.name,ingredients:item.ingredients}])}}
className="btn-xs btn-light"
type="button"
>
Make {item.name}
</button>
After that i need to compare that menu array's ingName and unit fields to calculate total ingredient need for ex. according to above array total is like
total : egg 4pcs , water 0.06 l , salt 2.0 pinch , olive oil 2.0 tablespoons
I tried this :
menu.map(item => item.ingredients).map((x,index)=> console.log(x[index].ingName))
it gets ingName property but after that i stuck.Thanks for help.
Edit :
React Solution : First declared Shyam's solution as function and used useeffect hook for to calculate total ingredients when user clicks button, useeffect updating total array.
const ingredientFunc = (input1,input2) => {
const output = input1.reduce(
(acc, input) => {
const matchedItem =
input2.length > 0 &&
input2.find((item) => item.ingName === input.ingName);
if (matchedItem) {
const updatedItem = {
ingName: input.ingName,
quantity: Number(input.quantity) + Number(matchedItem.quantity),
unit: input.unit,
};
acc.item.push(updatedItem);
acc.toFilter.push(matchedItem.ingName);
} else {
acc.item.push(input);
}
return acc;
},
{ item: [], toFilter: [] }
);
const filteredOutput = input2.filter(
(item) => !output.toFilter.includes(item.ingName)
);
const totalValues = [...output.item, ...filteredOutput];
setTotal(totalValues);
}
React.useEffect(() => {
if(menu.length === 1 ){
setTotal(menu[0].ingredients);
}
if(menu.length === 2){
const input1 = menu[0].ingredients;
const input2 = menu[1].ingredients;
ingredientFunc(input1,input2)
}
if(menu.length >= 3){
const input1 = total;
const input2 = menu[indexCount].ingredients;
ingredientFunc(input1,input2);
}
},[menu.length,indexCount]);
And modified button
<button
value={item.id}
onClick={(e) => {
setMenu([
...menu,
{ name: item.name, ingredients: item.ingredients },
]);
setCount(indexCount+1);
}}
className="btn-xs btn-light"
type="button"
>
Used indexCount state to locate last added recipe's index.
Upvotes: 2
Views: 142
Reputation: 5497
const input1 = [{ingName: "egg", quantity: "2.0", unit: "pcs"},
{ingName: "water", quantity: "0.03", unit: "l"},
{ingName: "salt", quantity: "1.0", unit: "pinch"}];
const input2 = [{ingName: "egg", quantity: "2.0", unit: "pcs"},
{ingName: "water", quantity: "0.03", unit: "l"},
{ingName: "salt", quantity: "1.0", unit: "pinch"},
{ingName: "olive oil", quantity: "2.0", unit: "tablespoons"}];
const output = input1.reduce((acc,input) => {
const matchedItem = input2.length > 0 && input2.find(item => item.ingName === input.ingName);
if(matchedItem){
const updatedItem = {
ingName: input.ingName,
quantity: Number(input.quantity) + Number(matchedItem.quantity),
unit: input.unit
}
acc.item.push(updatedItem);
acc.toFilter.push(matchedItem.ingName)
} else {
acc.item.push(input)
}
return acc;
}, {item:[] , toFilter: []});
const getFinalReceipes = (input1, input2) => {
const output = input1.reduce((acc,input) => {
const matchedItem = input2.length > 0 && input2.find(item => item.ingName === input.ingName);
if(matchedItem){
const updatedItem = {
ingName: input.ingName,
quantity: Number(input.quantity) + Number(matchedItem.quantity),
unit: input.unit
}
acc.item.push(updatedItem);
acc.toFilter.push(matchedItem.ingName)
} else {
acc.item.push(input)
}
return acc;
}, {item:[] , toFilter: []});
const filteredOutput = input2.filter(item => !output.toFilter.includes(item.ingName));
const totalValues = [...output.item, ...filteredOutput];
return totalValues;
}
const mergedReceipes1And2 = getFinalReceipes(input1, input2);
// Pass the merged result as the first argument
const mergedReceipe3 = getFinalReceipes(mergedReceipes1And2, [{ingName: "sugar", quantity: "1.0", unit: "pinch"}])
console.log(mergedReceipe3)
Upvotes: 1