Javascript 比较对象值数组(如果等于),将其加总
每当用户点击make pizza或其他菜谱时,我的应用程序中就有一个如上所述的数组结构,它将菜谱信息添加到下面给出的新菜单状态Javascript 比较对象值数组(如果等于),将其加总,javascript,arrays,reactjs,Javascript,Arrays,Reactjs,每当用户点击make pizza或其他菜谱时,我的应用程序中就有一个如上所述的数组结构,它将菜谱信息添加到下面给出的新菜单状态 [{ingName: "egg", quantity: "2.0", unit: "pcs"}, {ingName: "water", quantity: "0.03", unit: "l"}, {ingName: "
[{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"]
我试过这个:
total : egg 4pcs , water 0.06 l , salt 2.0 pinch , olive oil 2.0 tablespoons
它得到了ingName属性,但之后我卡住了。谢谢你的帮助
编辑:
反应溶液:
首先将Shyam的解决方案声明为函数,并在用户单击按钮时使用useeffect钩子计算总成分,useeffect更新总数组
menu.map(item => item.ingredients).map((x,index)=> console.log(x[index].ingName))
和修改按钮
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]);
{
设置菜单([
…菜单,
{name:item.name,components:item.components},
]);
设置计数(indexCount+1);
}}
className=“btn xs btn灯”
type=“按钮”
>
使用indexCount状态查找上次添加的配方索引。
const input1=[{ingName:“egg”,数量:“2.0”,单位:“pcs”},
{ingName:“水”,数量:“0.03”,单位:“l”},
{ingName:“盐”,数量:“1.0”,单位:“捏”}];
常量输入2=[{ingName:“egg”,数量:“2.0”,单位:“pcs”},
{ingName:“水”,数量:“0.03”,单位:“l”},
{ingName:“盐”,数量:“1.0”,单位:“捏”},
{ingName:“橄榄油”,数量:“2.0”,单位:“大汤匙”};
常量输出=输入1.减少((acc,输入)=>{
const matchedItem=input2.length>0&&input2.find(item=>item.ingName==input.ingName);
if(matchedItem){
常量updateItem={
ingName:input.ingName,
数量:编号(输入数量)+编号(匹配项数量),
单位:input.unit
}
附件项推送(更新编辑项);
根据过滤器推送(匹配项ingName)
}否则{
附件项推送(输入)
}
返回acc;
},{item:[],toFilter:[]});
const getFinalReceipes=(输入1,输入2)=>{
常量输出=输入1.减少((acc,输入)=>{
const matchedItem=input2.length>0&&input2.find(item=>item.ingName==input.ingName);
if(matchedItem){
常量updateItem={
ingName:input.ingName,
数量:编号(输入数量)+编号(匹配项数量),
单位:input.unit
}
附件项推送(更新编辑项);
根据过滤器推送(匹配项ingName)
}否则{
附件项推送(输入)
}
返回acc;
},{item:[],toFilter:[]});
常量filteredOutput=input2.filter(item=>!output.toFilter.includes(item.ingName));
const totalValues=[…output.item,…filteredOutput];
返回总值;
}
const mergedReceipes1和2=getFinalReceipes(输入1,输入2);
//将合并结果作为第一个参数传递
const mergedReceipe3=getFinalReceipes(mergedReceipes1和2,[{ingName:“糖”,数量:“1.0”,单位:“掐”}])
console.log(mergedReceipe3)
(Number(input.quantity)+Number(matchedItem.quantity)).toFixed(2)
最好添加toFixed(2)当添加两个带小数的数字时。很棒的解决方案适用于两个数组,但当用户添加第三个配方以列出它时,需要将其与totalvalues数组合并。在这种情况下,我建议您将上述代码作为一个函数,并更改传递输入的方式。将代码重构为一个函数,以便现在您可以可以通过“n”个接收。这里需要注意的一点是将合并结果传递给函数。我得到了您的最终重构,但在react状态下执行此操作比我想象的要困难。感谢您的所有努力,我将尽快编辑我的react way解决方案。我将您的评论标记为答案。
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]);
<button
value={item.id}
onClick={(e) => {
setMenu([
...menu,
{ name: item.name, ingredients: item.ingredients },
]);
setCount(indexCount+1);
}}
className="btn-xs btn-light"
type="button"
>