【问题标题】:How to derive new objects value from two different arrays in Javascript如何从Javascript中的两个不同数组派生新对象值
【发布时间】:2021-08-11 04:36:55
【问题描述】:

我有两个数组如下,

var day1 = [{id: 1, type:"20H", cases: 30, fail: 5},
                {id: 1, type:"12C", cases: 10, fail: 3},
                {id: 1, type:"4B", cases: 20, fail: 8}];
              
var day5 = [{id: 5, type:"12C" ,cases: 5, fail: 2},
             {id: 5, type:"4B", cases: 12, fail: 3},
             {id: 5, type:"20H", cases: 20, fail: 6}];

期待下面的数组结果,

var result = [{id: 1, type:"20H", caseCount: 30, failCount: 5, difference: 10, diffPercentage: 50.00},
              {id: 1, type:"12C", caseCount: 10, failCount: 3, difference: 5, diffPercentage: 100.00},
              {id: 1, type:"4B", caseCount: 20, failCount: 8, difference: 8, diffPercentage: 66.66}];

diff和diffPercentage的逻辑如下,

在这里,我不知道如何获取两个数组之间的匹配值并继续。

if(day1.type === day5.type){
    difference = day1.cases - day5.cases;//Here, 30-20 = 10
    diffPercentage = ((day1.cases - day5.cases)/(day5.cases)*100).toFixed(2);// 10/20 * 100 = 50.00
}

尝试了以下,

result = [];

day1.forEach(function(day1Items, idx){
    var day5Items = day5[idx];
    var outputElements = {};
    if(day1Items && day5Items){            
      if(day1Items.type == day5Items.type)){ //Here, I am not getting how to get the matched value between two array and proceed.
        console.log("Inside if block2"); //it is coming here, because, the if condition going index wise check
        outputElements.id = day1Items.id;
        outputElements.type = day1Items.type;
        outputElements.caseCount = day1Items.cases;
        outputElements.failCount = day1Items.fail;
        outputElements.difference = day1Items.cases - day5Items.cases;//Here, I need to get the cases value respective type matched
        outputElements.diffPercentage = ((day1.cases - day5.cases)/(day5.cases)*100).toFixed(2);
        result.push(outputElements);
      }
    }
});

console.log(result);

【问题讨论】:

    标签: javascript arrays underscore.js javascript-objects


    【解决方案1】:

    这应该可行:

     var day1 = [{id: 1, type:"20H", cases: 30, fail: 5},
                        {id: 1, type:"12C", cases: 10, fail: 3},
                        {id: 1, type:"4B", cases: 20, fail: 8}];
                  
        var day5 = [{id: 5, type:"12C" ,cases: 5, fail: 2},
                     {id: 5, type:"4B", cases: 12, fail: 3},
                     {id: 5, type:"20H", cases: 20, fail: 6}];
        
            let result = []
            
            day1.forEach(d1 => {
                const day5Item = day5.find(d5 => d5.type === d1.type);
                if(day5Item){
                    let difference = d1.cases - day5Item.cases;
                    let diffPercentage = (difference/day5Item.cases*100).toFixed(2)
            
                    result.push({
                        id:d1.id,type:d1.type,caseCount:d1.cases,failCount:d1.fail,difference,diffPercentage
                    })
                }
            });
            
            console.log(result);

    【讨论】:

    • 谢谢拉朱·艾哈迈德。我也向你学习了 reduce()。一张小纸条。 result.push 有一个额外的逗号,这会导致未捕获的语法错误。我纠正了我的立场。
    • 抱歉,我可能点击了两次。我编辑了代码。不客气。
    【解决方案2】:

    您可以使用Map 来实现此目的。

        var day1 = [
              { id: 1, type: "20H", cases: 30, fail: 5 },
              { id: 1, type: "12C", cases: 10, fail: 3 },
              { id: 1, type: "4B", cases: 20, fail: 8 }
         ];
    
         var day5 = [
              { id: 5, type: "12C", cases: 5, fail: 2 },
              { id: 5, type: "4B", cases: 12, fail: 3 },
              { id: 5, type: "20H", cases: 20, fail: 6 }
         ];
    
    
         function merge(arr1, arr2) {
           const hashMap = new Map();
           arr1.forEach((elem) => {
           const elemClone = {
             ...elem,
             failCount: elem.fail,
             caseCount: elem.cases
           };
           delete elemClone.fail;
           delete elemClone.cases;
           hashMap.set(elem.type, elemClone);
         });
    
         arr2.forEach((elem) => {
           if (hashMap.has(elem.type)) {
             const difference = Math.abs(elem.cases -
               hashMap.get(elem.type).caseCount);
             const diffPercentage = Number(parseFloat((difference / elem.cases) 
               * 100).toFixed(2));
             hashMap.set(elem.type, {
               ...hashMap.get(elem.type),
               difference,
               diffPercentage
              });
            } else {
              hashMap.set(elem.type, elem);
            }
          });
    
         return Array.from(hashMap.values());
       }
    
    console.log(merge(day1, day5));
    

    【讨论】:

      【解决方案3】:

      这是您的代码的更正版本。

      您的代码的问题是,您正在使用 array.forEach 循环遍历 day1 数组,并通过使用 indexday5 数组中选择匹配节点。那是磨损的,这仅在数组与类型的顺序相同时才有效。而不是使用var day5Items = day5[idx]; 进行选择,您必须使用Array.find 从第5 天选择节点并检查类型。 Thil 将为您提供所需的节点。

      另外计算diffPercentage也有错误

      应该是outputElements.diffPercentage = ((day1Items.cases - day5Items.cases)/(day5Items.cases)*100).toFixed(2);,而不是outputElements.diffPercentage = ((day1.cases - day5.cases)/(day5.cases)*100).toFixed(2); day1day5 是数组。您无法访问 day1.casesday5.cases 而应该是 day1Items.casesday5Items.cases

      var day1 = [
          { id: 1, type: "20H", cases: 30, fail: 5 },
          { id: 1, type: "12C", cases: 10, fail: 3 },
          { id: 1, type: "4B", cases: 20, fail: 8 }
      ];
      
      var day5 = [
          { id: 5, type: "12C", cases: 5, fail: 2 },
          { id: 5, type: "4B", cases: 12, fail: 3 },
          { id: 5, type: "20H", cases: 20, fail: 6 },
      ];
      const result = [];
      
      day1.forEach(function(day1Items, idx){
          // You cannot simply select with index.
          // Instead make use of `Array.find` to select the node from day5 Array with the condition
          // var day5Items = day5[idx];
          var day5Items = day5.find((node) => node.type === day1Items.type)
          var outputElements = {};
          if(day1Items && day5Items){            
            if(day1Items.type == day5Items.type){ //Here, I am not getting how to get the matched value between two array and proceed.
              outputElements.id = day1Items.id;
              outputElements.type = day1Items.type;
              outputElements.caseCount = day1Items.cases;
              outputElements.failCount = day1Items.fail;
              outputElements.difference = day1Items.cases - day5Items.cases;//Here, I need to get the cases value respective type matched
              // Calculation was wrong here
              outputElements.diffPercentage = ((day1Items.cases - day5Items.cases)/(day5Items.cases)*100).toFixed(2);
              result.push(outputElements);
            }
          }
      });
      
      console.log(result);

      简化方法

      使用Array.reduce

      var day1 = [
        { id: 1, type: "20H", cases: 30, fail: 5 }, 
        { id: 1, type: "12C", cases: 10, fail: 3 }, 
        { id: 1, type: "4B", cases: 20, fail: 8 }, 
        { id: 1, type: "49B", cases: 20, fail: 8 } 
      ];;
      
      var day5 = [
        { id: 5, type: "12C", cases: 5, fail: 2 },
        { id: 5, type: "4B", cases: 12, fail: 3 },
        { id: 5, type: "20H", cases: 20, fail: 6 },
      ];
      
      const result = day1.reduce((acc, curr) => {
        const insertNode = { id: curr.id, type: curr.type, caseCount: curr.cases, failCount: curr.fail };
        const d5Node = day5.find((node) => node.type === curr.type);
        if (d5Node) {
          insertNode.difference = curr.cases - d5Node.cases;
          insertNode.diffPercentage = (insertNode.difference / d5Node.cases * 100).toFixed(2);
        } else {
          // Handle the calculation logic here
          insertNode.difference = curr.cases;
          insertNode.diffPercentage = insertNode.difference * 100;
        }
        acc.push(insertNode);
        return acc;
      }, []);
      console.log(result);

      【讨论】:

      • 非常感谢 Nitheesh 的代码和解释。现在,我明白了,代码按预期工作正常。
      • @VadivelA 欢迎您。如果这是您要查找的内容,请批准此答案。很高兴也能获得支持。
      • 嗨 Nitheesh,这里还需要处理一个奇怪的行为。 if var day1 = [{id: 1, type:"20H", case: 30, fail: 5}, {id: 1, type:"12C", case: 10, fail: 3}, {id: 1,类型:“4B”,案例:20,失败:8},{id:1,类型:“49B”,案例:20,失败:8}];还有一个类型为 49B 的条目,这些条目也想添加到结果数组中。
      • @VadivelA 这可以通过检查day5数组中是否存在匹配节点来处理。我已经在我的Array.reduce 解决方案中处理了这个问题。
      • @VadivelA 请批准这个答案。很高兴也能获得支持。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-06
      • 1970-01-01
      • 2013-02-14
      • 1970-01-01
      • 1970-01-01
      • 2021-07-17
      • 1970-01-01
      相关资源
      最近更新 更多