完全合并两个多维数组并创建一个新数组

时间:2018-06-01 19:09:41

标签: javascript arrays node.js

我有两个要合并的数组,但也添加了数组的“Count”和“Total”部分。

数组一是:(较小)

[ { ReasonCode: '', Count: 2, Total: 15.63 },
  { ReasonCode: '01', Count: 13, Total: -144 },
  { ReasonCode: '03', Count: 7, Total: -394.87 },
  { ReasonCode: '04', Count: 128, Total: -3556.1 },
  { ReasonCode: '07', Count: 2, Total: -4.83 },
  { ReasonCode: '09', Count: 192, Total: -20826.25 } ]

数组二是:(更大)

[ { ReasonCode: '', Count: 6, Total: 412.21 },
  { ReasonCode: '01', Count: 7, Total: -9.75 },
  { ReasonCode: '02', Count: 5, Total: -37.03 },
  { ReasonCode: '04', Count: 162, Total: -1199.16 },
  { ReasonCode: '05', Count: 1, Total: -3.8 },
  { ReasonCode: '06', Count: 2, Total: -58.83 },
  { ReasonCode: '07', Count: 76, Total: -507.23 },
  { ReasonCode: '09', Count: 41, Total: -743.07 } ]

我正在使用此函数合并它们并创建新数组。

function CombineArrays(BiggerArray, SmallerArray, NewArray) {
  BiggerArray.forEach(function (BA) {
    let match = false;

    SmallerArray.forEach(function (SA) {

        if(BA.ReasonCode === SA.ReasonCode){

            match = true;

            BA.Count += SA.Count;
            BA.Total += SA.Total;
            BA.ReasonCode = SA.ReasonCode;

            NewArray.push(BA);

        }
    });

    if(!match) NewArray.push(BA);

  });
}

从该函数生成的数组缺少第一个数组中的“ReasonCode:'03'”。我怎样才能这样做,它将添加两个数组中的所有数组对象,并将所需的两列相加。

[ { ReasonCode: '', Count: 8, Total: 427.84 },
  { ReasonCode: '01', Count: 20, Total: -153.75 },
  { ReasonCode: '02', Count: 5, Total: -37.03 },
  { ReasonCode: '04', Count: 290, Total: -4755.26 },
  { ReasonCode: '05', Count: 1, Total: -3.8 },
  { ReasonCode: '06', Count: 2, Total: -58.83 },
  { ReasonCode: '07', Count: 78, Total: -512.0600000000001 },
  { ReasonCode: '09', Count: 233, Total: -21569.32 } ]

提前谢谢。

5 个答案:

答案 0 :(得分:1)

我会循环遍历最小的数组,如果该项不在大数组中,则添加它,否则添加到Count/Total

const arr1 = [{ ReasonCode: '', Count: 2, Total: 15.63 },
{ ReasonCode: '01', Count: 13, Total: -144 },
{ ReasonCode: '03', Count: 7, Total: -394.87 },
{ ReasonCode: '04', Count: 128, Total: -3556.1 },
{ ReasonCode: '07', Count: 2, Total: -4.83 },
{ ReasonCode: '09', Count: 192, Total: -20826.25 }]

const arr2 = [{ ReasonCode: '', Count: 6, Total: 412.21 },
{ ReasonCode: '01', Count: 7, Total: -9.75 },
{ ReasonCode: '02', Count: 5, Total: -37.03 },
{ ReasonCode: '04', Count: 162, Total: -1199.16 },
{ ReasonCode: '05', Count: 1, Total: -3.8 },
{ ReasonCode: '06', Count: 2, Total: -58.83 },
{ ReasonCode: '07', Count: 76, Total: -507.23 },
{ ReasonCode: '09', Count: 41, Total: -743.07 }]


function CombineArrays(biggest, smallest) {
  // Create a new instance of the bigger array
  let result = [].concat(biggest)
  smallest.forEach(smallItem => {
    // Try to get the item from the bigger list
    var bigItem = result.find(item => item.ReasonCode == smallItem.ReasonCode)
    // If it is not in the bigger list, add it
    if (!bigItem) result.push(smallItem)
    // If it is in the bigger list, then increment count/total by the small item amounts
    else {
      bigItem.Count += smallItem.Count
      bigItem.Total += smallItem.Total
    }
  })
  return result
}

console.log(CombineArrays(arr2, arr1))

答案 1 :(得分:1)

我会通过concat数组执行此操作,然后reduce匹配正确的ReasonCode

let arr1 = [ { ReasonCode: '', Count: 2, Total: 15.63 },
  { ReasonCode: '01', Count: 13, Total: -144 },
  { ReasonCode: '03', Count: 7, Total: -394.87 },
  { ReasonCode: '04', Count: 128, Total: -3556.1 },
  { ReasonCode: '07', Count: 2, Total: -4.83 },
  { ReasonCode: '09', Count: 192, Total: -20826.25 } ];

let arr2 = [ { ReasonCode: '', Count: 6, Total: 412.21 },
  { ReasonCode: '01', Count: 7, Total: -9.75 },
  { ReasonCode: '02', Count: 5, Total: -37.03 },
  { ReasonCode: '04', Count: 162, Total: -1199.16 },
  { ReasonCode: '05', Count: 1, Total: -3.8 },
  { ReasonCode: '06', Count: 2, Total: -58.83 },
  { ReasonCode: '07', Count: 76, Total: -507.23 },
  { ReasonCode: '09', Count: 41, Total: -743.07 } ];
  
// Merge the arrays to a single one - Can be more if you need, just append them in concat()
let source = arr1.concat(arr2);

// Reduce the array holding all separated values to a new one
// with distinct ReasonCodes - the last argument `[]` is the initial accumulator value
let merged = source.reduce((accumulator, candidate) => {
  // Check if this candidate is already in the accumulator
  let index = accumulator.findIndex(
    // Make it short with a fat arrow function that checks for an existing ReasonCode
    existing => existing.ReasonCode === candidate.ReasonCode
  );
  if(index > -1) {
    // If found in results, just increment the existing values with the ones from the candidate
    accumulator[index].Count += candidate.Count;
    accumulator[index].Total += candidate.Total;
  } else {
    // If candidate was not present yet, push it to the accumulator
    accumulator.push(candidate);
  }
  return accumulator;
}, []);

console.log(merged);

使用此方法,您可以保证合并所有ReasonCodes与合并的数组。有关reducehttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

的更多信息

答案 2 :(得分:1)

尝试以下方法:



var arr1 = [ { ReasonCode: '', Count: 2, Total: 15.63 },
  { ReasonCode: '01', Count: 13, Total: -144 },
  { ReasonCode: '03', Count: 7, Total: -394.87 },
  { ReasonCode: '04', Count: 128, Total: -3556.1 },
  { ReasonCode: '07', Count: 2, Total: -4.83 },
  { ReasonCode: '09', Count: 192, Total: -20826.25 } ];
  
  var arr2 = [ { ReasonCode: '', Count: 6, Total: 412.21 },
  { ReasonCode: '01', Count: 7, Total: -9.75 },
  { ReasonCode: '02', Count: 5, Total: -37.03 },
  { ReasonCode: '04', Count: 162, Total: -1199.16 },
  { ReasonCode: '05', Count: 1, Total: -3.8 },
  { ReasonCode: '06', Count: 2, Total: -58.83 },
  { ReasonCode: '07', Count: 76, Total: -507.23 },
  { ReasonCode: '09', Count: 41, Total: -743.07 } ];
  
  var map = {};
  for(var i = 0; i < arr1.length; i++){
    map[arr1[i].ReasonCode] = {
      "index" : i
    };
  }
  var result = [];
  for(var i = 0; i < arr2.length; i++){
    if(map[arr2[i].ReasonCode]){
      arr2[i].Count += arr1[map[arr2[i].ReasonCode].index].Count;
      arr2[i].Total += arr1[map[arr2[i].ReasonCode].index].Total;
      map[arr2[i].ReasonCode].found = true;
    } 
    result.push(arr2[i]);
  }
  Object.keys(map).forEach(function(key){
      if(!map[key].found)
        result.push(arr1[map[key].index]);
  });
  console.log(result);
&#13;
&#13;
&#13;

答案 3 :(得分:1)

&#13;
&#13;
var array1= [ { ReasonCode: '', Count: 2, Total: 15.63 },
  { ReasonCode: '01', Count: 13, Total: -144 },
  { ReasonCode: '03', Count: 7, Total: -394.87 },
  { ReasonCode: '04', Count: 128, Total: -3556.1 },
  { ReasonCode: '07', Count: 2, Total: -4.83 },
  { ReasonCode: '09', Count: 192, Total: -20826.25 } ];
  
  var array2   = [ { ReasonCode: '', Count: 6, Total: 412.21 },
  { ReasonCode: '01', Count: 7, Total: -9.75 },
  { ReasonCode: '02', Count: 5, Total: -37.03 },
  { ReasonCode: '04', Count: 162, Total: -1199.16 },
  { ReasonCode: '05', Count: 1, Total: -3.8 },
  { ReasonCode: '06', Count: 2, Total: -58.83 },
  { ReasonCode: '07', Count: 76, Total: -507.23 },
  { ReasonCode: '09', Count: 41, Total: -743.07 } ];

function CombineArrays(BiggerArray, SmallerArray) {
    var NewObject = {};
    BiggerArray.forEach(function(BA) {
        var temp = NewObject[BA.ReasonCode] || {};
        temp.Count = temp.Count ? temp.Count + BA.Count : BA.Count;
        temp.Total = temp.Total ? temp.Total + BA.Total : BA.Total;
        temp.ReasonCode = BA.ReasonCode;

        NewObject[BA.ReasonCode] = temp;
    })
    SmallerArray.forEach(function(SA) {
        var temp = NewObject[SA.ReasonCode] || {};
        temp.Count = temp.Count ? temp.Count + SA.Count : SA.Count;
        temp.Total = temp.Total ? temp.Total + SA.Total : SA.Total;
        temp.ReasonCode = SA.ReasonCode;
        NewObject[SA.ReasonCode] = temp;

    });

    return NewObject;
}
console.log(CombineArrays(array1, array2));
&#13;
&#13;
&#13;

答案 4 :(得分:1)

你的algorythm效率不高。如果找到forEach,您的内部ReasonCode循环将遍历数组的每个元素。如果您使用了常规数组,则可以在break内执行if

这是我的答案,一种不同的方法。

将对象用作地图非常适合您的情况,因为您可以轻松存储和访问每个ReasonCode,您还可以将实际对象作为值附加。

let map = {};

function execute(array) {
    for(let i = 0; i < array.length; i++) {
        let SA = array[i];
        if( SA.ReasonCode in map === false ) {
            map[SA.ReasonCode] = SA;
        }
        else {
            let obj = map[SA.ReasonCode];
            obj.Count += SA.Count;
            obj.Total += SA.Total;
        }
    }
}

execute(SmallerArray);
execute(BiggerArray);

console.log(Object.values(map));