Home > Software design >  Combine value with same date in multidimensional array in Javascript
Combine value with same date in multidimensional array in Javascript

Time:05-19

I have one array which has two values one date and an amount but there is the same date with a different value at a different index so I need to merge those values into the same date in a multidimensional javascript array

current array

var arry = [
['2021-05-01',100], 
['2021-05-02',300], 
['2021-05-03',200], 
['2021-05-01',150],
['2021-05-02',300], 
['2021-05-01',600],
['2021-05-04',120]
]

Expected Result Array

var arry = [
['2021-05-01',850], 
['2021-05-02',600], 
['2021-05-03',200], 
['2021-05-04',120]]

Can anybody help? I really appreciate any help you can provide.

CodePudding user response:

You can use reduce method:

var arry = [
  ['2021-05-01',100], 
  ['2021-05-02',300], 
  ['2021-05-03',200], 
  ['2021-05-01',150],
  ['2021-05-02',300], 
  ['2021-05-01',600],
  ['2021-05-04',120]
];

const data = arry.reduce((list, [date, value]) =>  {
  list[date] = (list[date] ?? 0)   value;
  return list;
}, {});
const list = Object.entries(data); // if you want the array

console.log(list);

CodePudding user response:

Here is a solution using reduce. I'm creating an object grouped by date and taking the values array of it

var arry = [['2021-05-01',100], ['2021-05-02',300], ['2021-05-03',200], ['2021-05-01',150],['2021-05-02',300], ['2021-05-01',600],['2021-05-04',120]]

const res = Object.values(arry.reduce((acc,[date,val])=> {
    acc[date] = acc[date] || [date,0]
  acc[date][1] =val
  return acc
},{}))

console.log(res)

CodePudding user response:

You could likely just loop through the list, and at each value in the list check all of the values that came before to see if it is a repeat. Something like the following would work:

var array = [
  ['2021-05-01',100], 
  ['2021-05-02',300], 
  ['2021-05-03',200], 
  ['2021-05-01',150],
  ['2021-05-02',300], 
  ['2021-05-01',600],
  ['2021-05-04',120]
]

var newArray = []; // where we will put the new merged values

for (var lookAtOldArray = 0; lookAtOldArray < array.length; lookAtOldArray  ) {
  // check all previous values in newArray up to this point:
  var checkNewArray; // declare out here for logic post loop
  for (checkNewArray = 0; checkNewArray < newArray.length; checkNewArray  ) {
    if (array[lookAtOldArray][0] == newArray[checkNewArray][0]) {
      // add to newArray number:
      newArray[checkNewArray][1]  = array[lookAtOldArray][1];
      break; // BREAK to signify we found a position
    }

    // otherwise keep looking
  }

  // because of the break, if checkNewArray == newArray.length, then we DID NOT find a duplicate (AKA: push to newArray with exact value in array)
  if (checkNewArray == newArray.length) {
     newArray.push(array[lookAtOldArray]);
  }
}

another interesting idea would be to use objects. The above strategy would require looking the data more times than necessary (n^2 for worst cases). With an object, you could use the date as a key, and the number as the value. With that, you could do something like this (assuming the same declaration of array:

var combinedDates = {};

for (var lookAtOldArray = 0; lookAtOldArray < array.length; lookAtOldArray  ) {
  combinedDates[array[lookAtOldArray][0]]  = array[lookAtOldArray[1];
}

You can tell this is a lot faster and simpler. The resulting object would look like this:

{
  "2021-05-01": 850,
  "2021-05-02": 600,
  "2021-05-03": 200,
  "2021-05-04": 120
}

I'm preferential to the second one because of the efficiency increase; you only ever have to look at each element in the initial array once (resulting in n, or linear, time complexity)!

If you want to combine the above object back into an array, you could then do:

// get object keys
var objectKeys = Object.keys(combinedDates);
var newArray = [];

// loop through keys
for (var makeObject = 0; makeObject < objectKeys.length; makeObject  ) {
  // create array with key (the date) and the number (the value stored at the key):
  newArray.push([objectKeys[makeObject][0], combinedDates[objectKeys[makeObject]]);
}
  • Related