Javascript 比较对象值数组(如果等于),将其加总

Javascript 比较对象值数组(如果等于),将其加总,javascript,arrays,reactjs,Javascript,Arrays,Reactjs,每当用户点击make pizza或其他菜谱时,我的应用程序中就有一个如上所述的数组结构,它将菜谱信息添加到下面给出的新菜单状态 [{ingName: "egg", quantity: "2.0", unit: "pcs"}, {ingName: "water", quantity: "0.03", unit: "l"}, {ingName: "

每当用户点击make pizza或其他菜谱时,我的应用程序中就有一个如上所述的数组结构,它将菜谱信息添加到下面给出的新菜单状态

    [{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"
                    >