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

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.