2

I've got some data:

const data = [
  [
    [1609459200000, 18],
    [1612137600000, 12],
    [1614556800000, 12],
    [1617231600000, 14]
  ],
  [
    [1609459200000, 30],
    [1612137600000, 501],
    [1614556800000, 81],
    [1617231600000, 82],
  ]

]

The long numbers are timestamps and I want to return an array as below:

const result = [{
  x: 1609459200000,
  y: 48
}, {
  x: 1612137600000,
  y: 513
}, {
  x: 1614556800000,
  y: 93
}, {
  x: 1617231600000,
  y: 96
}]

The X will contain the timestamp and the Y will be the sum of the values at the index 1 of each inner array, corresponding to each timestamp.

In case one of the array's element has more values than the other, it should sum it anyway as below:

const data = [
  [
    [1609459200000, 18],
    [1612137600000, 12],
    [1614556800000, 12],
    [1617231600000, 14]
  ],
  [
    [1609459200000, 30],
    [1612137600000, 501],
    [1614556800000, 81],
  ]

]

const result = [{
  x: 1609459200000,
  y: 48
}, {
  x: 1612137600000,
  y: 513
}, {
  x: 1614556800000,
  y: 93
}, {
  x: 1617231600000,
  y: 14
}]

My attempts were completely worthless and couldn't pass the part where the array is multidimensional

FAILED

const totals = data.reduce((total, curr, i) => {
  total = {
    x: curr[0][i],
    y: curr[1][i]
  }

}, {})

console.log('total', totals)

EDIT

The data array can have more than 2 sub arrays.

4
  • Are you always going to have only 2 subarrays in your data variable? Commented Aug 2, 2021 at 15:48
  • I can have many Commented Aug 2, 2021 at 15:51
  • And are they supposed to be having the same order of timestamps, only missing greater ones, none from in between? Commented Aug 2, 2021 at 15:52
  • @TusharShahi I wouldn't expect any reasonable solution to care about those things (the timestamp values or their ordering). Commented Aug 2, 2021 at 16:12

3 Answers 3

4

You can flatten the array and then perform a reduce operation over it, using an object to store the sum for each timestamp.

const data = [
  [
    [1609459200000, 18],
    [1612137600000, 12],
    [1614556800000, 12],
    [1617231600000, 14]
  ],
  [
    [1609459200000, 30],
    [1612137600000, 501],
    [1614556800000, 81],
    [1617231600000, 82],
  ]
];
const res = Object.values(data.flat().reduce((acc, [x,y])=>{
  (acc[x] ??= {x, y: 0}).y += y;
  return acc;
}, {}));
console.log(res);

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

Comments

0

const data = [
  [
    [1609459200000, 18],
    [1612137600000, 12],
    [1614556800000, 12],
    [1617231600000, 14]
  ],
  [
    [1609459200000, 30],
    [1612137600000, 501],
    [1614556800000, 81]
  ]
]

const arr = [...data.flat()
  .reduce((a, [x, y]) => {
    a.has(x) ? (a.get(x).y += y) : a.set(x, { y })
    return a
  }, new Map())].map(([x, { y }]) => ({ x, y }))


console.log(
  arr
)

Comments

0

You can achieve this in 3 steps:

  1. First you need to flat your array (even double flat in your case),
  2. Map elements into desired objects,
  3. Group by timestamp (x).

Step 2 and 3 might be swapped.

Example code:

const data = [[[16094592e5,18],[16121376e5,12],[16145568e5,12],[16172316e5,14]],[[16094592e5,30],[16121376e5,501],[16145568e5,81],[16172316e5,82]]];

const res = data.flatMap(e => e.flatMap(([x, y]) => ({x, y})))
                .reduce((acc, e) => {
                  const found = acc.find(x => x.x === e.x)
                  found ? found.y += e.y : acc.push(e)
                  return acc
                }, [])

console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; } /* ignore this */

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.