Mam dwie tablicy, które chcę połączyć, ale także dodać "liczyć" i "całkowitą" części tablicy.

Array One to: (mniejszy)

[ { 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 } ]

Array Dwa to: (Większy)

[ { 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 } ]

Używam tej funkcji, aby scalić je i tworzyć nową tablicę.

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);

  });
}

Tablica wykonana z funkcji brakuje "przyczyny:" 03 "" z pierwszej tablicy. Jak mogę to zrobić, aby dodać wszystkie obiekty tablicy z obu macierzy i dodam razem dwie potrzebne kolumny.

[ { 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 } ]

Z góry dziękuję.

0
kaydrae 1 czerwiec 2018, 22:09

5 odpowiedzi

Najlepsza odpowiedź

Pętli przez najmniejszą tablicę i jeśli przedmiot nie jest w dużej tablicy, dodaj go, w przeciwnym razie dodaj do 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
Get Off My Lawn 1 czerwiec 2018, 19:37

Spróbuj wykonać następujące czynności:

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);
1
amrender singh 1 czerwiec 2018, 19:41

Zrobiłbym to przez concat ING w tabliczce, a następnie reduce, dopasowując właściwe 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);

Dzięki tej metodzie gwarantujesz, że scalamy wszystkie kody z połączonych tablic. Więcej o reduce: HTTPS: //developer.mozilla.org/en-us/docs/web/javascript/plErence/global_objects/array/reduce.

1
wiesion 1 czerwiec 2018, 19:45

Twój Algorythm nie jest zbyt wydajny. Twoja wewnętrzna forEach pętla przejdzie przez każdy element tablicy, jeśli zostanie znaleziony ReasonCode. Jeśli używałeś tablic regularnych, możesz po prostu break wykonanie w twoim {x3}}.

Oto moja odpowiedź, trochę innego podejścia.

Korzystanie z obiektu jako mapę jest idealna dla Twojej sprawy, ponieważ można łatwo przechowywać i uzyskać dostęp do każdego ReasonCode s, można również dołączyć rzeczywisty obiekt jako wartość.

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));
1
user5466293user5466293 1 czerwiec 2018, 19:44
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));
1
Nishant Dixit 1 czerwiec 2018, 19:40