简体   繁体   中英

how to get a cumulative total array from 3 two dimensional arrays

I have 3 two dimensional arrays as given below which are series data to plot lines on a graph with the key being the timestamp.

const arr1 = [[1641013200000,1881],[1643691600000,38993],[1646110800000,41337],[1648785600000,78856],[1651377600000,117738],[1654056000000,119869],[1656648000000,157799],[1659326400000,196752],[1662004800000,199061],[1664596800000,237034],[1667275200000,239153],[1669870800000,269967]]
const arr2 = [[1641013200000,1302],[1643691600000,3347],[1646110800000,4754],[1648785600000,6948],[1651377600000,9725],[1654056000000,11314],[1656648000000,13787],[1659326400000,16666],[1662004800000,18370],[1664596800000,20876],[1667275200000,22384],[1669870800000,23560]]
const arr3 = [[1643691600000,67350],[1648785600000,134700],[1651377600000,202148],[1654056000000,202270],[1656648000000,269843],[1659326400000,337346],[1662004800000,337470],[1664596800000,404861],[1667275200000,404889],[1669870800000,472239]]

I want to plot another series line which gives the cumulative total of all three arrays values (Note: if a timestamp is not present in either of the arrays, add the previous index value)

const totalArray = [
[1641013200000,3183],[1643691600000, 109690],[1646110800000, 113441],[1648785600000, 220504],
[1651377600000, 329611],[1654056000000, 333453],[1656648000000, 441429],[1659326400000, 550764],
[1662004800000, 554901],[1664596800000, 662771],[1667275200000, 666426],[1669870800000, 765766]
]

I have tried this, but some values are incorrect due to the timestamp not being present in either one

Approach:

const arr1 = [[1641013200000,1881],[1643691600000,38993],[1646110800000,41337],[1648785600000,78856],[1651377600000,117738],[1654056000000,119869],[1656648000000,157799],[1659326400000,196752],[1662004800000,199061],[1664596800000,237034],[1667275200000,239153],[1669870800000,269967]];
const arr2 = [[1641013200000,1302],[1643691600000,3347],[1646110800000,4754],[1648785600000,6948],[1651377600000,9725],[1654056000000,11314],[1656648000000,13787],[1659326400000,16666],[1662004800000,18370],[1664596800000,20876],[1667275200000,22384],[1669870800000,23560]];
const arr3 = [[1643691600000,67350],[1648785600000,134700],[1651377600000,202148],[1654056000000,202270],[1656648000000,269843],[1659326400000,337346],[1662004800000,337470],[1664596800000,404861],[1667275200000,404889],[1669870800000,472239]];

const calculateTotal = () => {
    var ret;

    for(let a3 of arr3) {
      var index = arr1.map(function(el){return el[0];}).indexOf(a3[0]);
      console.log(index);
      if (index === -1) {
        ret = arr1[index][0];
        console.log(ret);
      }
    }
    let unsortedArr = arr1.concat(arr2, arr3);
    var sortedArray = unsortedArr.sort((a, b) => a[0] - b[0]);
    var added = addArray(sortedArray);
    console.log("Curent Output: " + JSON.stringify(added));
} 

const addArray = (tuples) => {
    var hash = {},
      keys = [];
      tuples.forEach(function (tuple) {
        var key = tuple[0],
            value = tuple[1];
        if (hash[key] === undefined) {
          keys.push(key);
          hash[key] = value;
        } else {
          hash[key] += value;
        }
      });
      return keys.map(function (key) {
        return([key, hash[key]]);
      });
}

calculateTotal();

[Code Sandbox Link][1] [1]: https://codesandbox.io/s/tender-blackburn-rgwns3?file=/src/App.js:1349-1761

Is it possible to achieve this?

In your code there is this:

if (index === -1) {
    ret = arr1[index][0];

But that assignment will fail as arr1[-1] is not defined.

Then when you do:

let unsortedArr = arr1.concat(arr2, arr3);

...you end up with an array that does not have the knowledge to use default values (from a previous index) when any of the three arrays has a "missing" time stamp.

I would suggest this approach:

  1. Collect all the unique timestamps (from all arrays) into a Map, and associate arrays to each of those keys: these will be empty initially.
  2. Populate those arrays with the timestamps from the original arrays
  3. Get the sorted list of entries from that map
  4. Fill the "gaps" by carrying forward values to a next array when the corresponding slot is undefined. At the same time sum up these values for the final output.

Here is an implementation:

 function mergeArrays(...arrays) { const map = new Map(arrays.flatMap(arr => arr.map(([stamp]) => [stamp, []]))); arrays.forEach((arr, i) => { for (const [timeStamp, value] of arr) { map.get(timeStamp)[i] = value; } }); const state = Array(arrays.length).fill(0); return Array.from(map).sort(([a], [b]) => a - b).map(([timeStamp, arr], i) => [timeStamp, state.reduce((sum, prev, j) => sum + (state[j] = arr[j]?? prev), 0)] ); } // Example run const arr1 = [[1641013200000,1881],[1643691600000,38993],[1646110800000,41337],[1648785600000,78856],[1651377600000,117738],[1654056000000,119869],[1656648000000,157799],[1659326400000,196752],[1662004800000,199061],[1664596800000,237034],[1667275200000,239153],[1669870800000,269967]]; const arr2 = [[1641013200000,1302],[1643691600000,3347],[1646110800000,4754],[1648785600000,6948],[1651377600000,9725],[1654056000000,11314],[1656648000000,13787],[1659326400000,16666],[1662004800000,18370],[1664596800000,20876],[1667275200000,22384],[1669870800000,23560]]; const arr3 = [[1643691600000,67350],[1648785600000,134700],[1651377600000,202148],[1654056000000,202270],[1656648000000,269843],[1659326400000,337346],[1662004800000,337470],[1664596800000,404861],[1667275200000,404889],[1669870800000,472239]]; const result = mergeArrays(arr1, arr2, arr3); console.log(result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM