Sirmorrison
Sirmorrison

Reputation: 23

How to merge an array of arrays with duplicate at index 0 into one array javascript

I have an array of arrays with date at index 0. I would love to check love to loop through the array and any date that matches with another, there values should be merged at.

this is what the array looks like and what i have tried..

var array = [
  [
    Date 2019-06-11T10:00:00.000Z,
    0,
    0,
    0,
    23
  ],
  [
    Date 019-06-11T10:00:00.000Z,
    0,
    0,
    2,
    0
  ],
  [
   Date 2019-16-11T12:00:00.000Z,
    0,
    56,
    0,
    0
  ],
  [
    Date 2019-16-11T12:00:00.000Z,
    3,
    0,
    0,
    0
  ]
]

var result = array.filter(function(v) {
  return this[v[0]] ?
    !Object.assign(this[v[0]], v) :
    (this[v[0]] = v)
}, []);
console.log(result);

I intend the output to be something like this, but the method seems to remove the duplicates.

var array = [[
  Date  2019-06-11T10:00:00.000Z,
    0,
    0,
    2,
    23
  ],[
   Date 2019-16-11T12:00:00.000Z,
    3,
    56,
    0,
    0
  ]]

an image of what the data looks like on the browser console

Upvotes: 1

Views: 279

Answers (3)

Nina Scholz
Nina Scholz

Reputation: 386560

A fast approach with an object.

var array = [[new Date('2019-06-11T10:00:00.000Z'), 0, 0, 0, 23], [new Date('2019-06-11T10:00:00.000Z'), 0, 0, 2, 0], [new Date('2019-06-16T12:00:00.000Z'), 0, 56, 0, 0], [new Date('2019-06-16T12:00:00.000Z'), 3, 0, 0, 0]],
    hash = {},
    i, j,
    result,
    item,
    key;

for (i = 0; i < array.length; i++) {
    item = array[i];
    key = item[0].toString();
    if (!hash[key]) {
        hash[key] = item.slice();
        continue;
    }
    for (j = 1; j < item.length; j++) hash[key][j] += item[j];
}

result = Object.values(hash);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

cнŝdk
cнŝdk

Reputation: 32145

Well there are a lot of conditions that needs to be taken into account in each merge operation, but you can use a combination of Array.some(), Array.filter() and Array.map() methods and go with something like this:

let result = [];
array.forEach((a, i) => {
  if (!result.some(x => x[0] == a[0])) {
    let found = array.filter((x, j) => {
      return i != j && x[0] == a[0];
    });
    if (found.length > 0) {
      a = a.map((e, ind) => {
        if (ind > 0)
          found.forEach(f => {
            e += f[ind];
          });
        return e;
      });
    }
    result.push(a);
  }
});

Demo:

var array = [
  [
    '2019-06-11T10:00:00.000Z',
    0,
    0,
    0,
    23
  ],
  [
    '2019-06-11T10:00:00.000Z',
    0,
    0,
    2,
    0
  ],
  [
    '2019-16-11T12:00:00.000Z',
    0,
    56,
    0,
    0
  ],
  [
    '2019-16-11T12:00:00.000Z',
    3,
    0,
    0,
    0
  ]
];

let result = [];

array.forEach((a, i) => {
  if (!result.some(x => x[0] == a[0])) {
    let found = array.filter((x, j) => {
      return i != j && x[0] == a[0];
    });
    if (found.length > 0) {
      a = a.map((e, ind) => {
        if (ind > 0)
          found.forEach(f => {
            e += f[ind];
          });
        return e;
      });
    }
    result.push(a);
  }
});
console.log(result);

Upvotes: 0

Kobe
Kobe

Reputation: 6446

You can use findIndex to check if the accumulator already has the 0 index of the new array, and merge the arrays if it does:

const arr = [['2019-06-11T10:00:00.000Z', 0, 0, 0, 23], ['2019-06-11T10:00:00.000Z', 0, 0, 2, 0], ['2019-16-11T12:00:00.000Z', 0, 56, 0, 0], ['2019-16-11T12:00:00.000Z', 3, 0, 0, 0]]

const sorted = arr.reduce((acc, a) => {
  const index = acc.findIndex(b => a[0] === b[0])
  index > -1 ? acc[index] = acc[index].map((b, i) => i ? b + a[i]: b) : acc.push(a)
  return acc
}, [])

console.log(sorted)

Upvotes: 1

Related Questions