1

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

3 Answers 3

1

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)

Sign up to request clarification or add additional context in comments.

Comments

0

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

6 Comments

Not to be rude but I'm not sure if that solution is viable. It clearly works but A isn't readable which leads to B, the question author won't improve his skills with a copy paste answer. So we'll get that same question again I suppose. Please don't get me wrong, I see you do a lot for SO which great quality. This is something that just popped up in my head.
this seems to work if the date is a string value "2016-08-26T00:00:00Z". Issue is the date index is a javascript date. i.sstatic.net/VMVBK.png . and it doesnt work.
you could take for the check the toString method: a[0].toString() === b[0].toString() which returns a comparable string.
too slow especially when processing over over 5000 array data.
Nice. I see you modified the solution. Thanks. The only issue is i want the date value as date. Im plotting the data on a graph and it doesnt take strings a values.
|
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.