Home > Enterprise >  Merging non-matching timeseries arrays in JS?
Merging non-matching timeseries arrays in JS?

Time:11-26

My question is of data manipulation.

Say I have multiple data arrays with the structure as follows:

[
  [timestamp1, value1],
  [timestamp2, value2],
  [timestamp3, value3],
  ...
  [timestampN, valueN]
]

With real data it could look e.g. like this:

[
  [1637837518000, 1.7],
  [1637837519000, 0.1],
  [1637837520000, 1.3],
  ...
  [1637837600000, 2.2]
]

The I need to merge multiple of such arrays into one, which is is easy if the time axes are matching. If I have e.g. three short sample arrays:

const arr1 = [
  [1637837518000, 1.7],
  [1637837519000, 0.1],
  [1637837520000, 1.3]
];
const arr2 = [
  [1637837518000, 4.5],
  [1637837519000, 0.3],
  [1637837520000, 7.2],
];
const arr3 = [
  [1637837518000, 1.2],
  [1637837519000, 2.1],
  [1637837520000, 3.0]
];

they would be merged into the following array, retaining the common time axis:

[
  [1637837518000, 1.7, 4.5, 1.2],
  [1637837519000, 0.1, 0.3, 2.1],
  [1637837520000, 1.3, 7.2, 3.0]
]

This is straightforward, but if the arrays are of different lengths where some arrays have a data point on a timestamp where others do not, what would be most efficient way of performing such parsing? I'm asking for an efficient solution as there can be a lot of data and slow parsing would result in a bad user experience. Also, the timestamps should be in order in the resulting array. It can be expected that within a single array the timestamps are in order.

Sample data for the problem I'm trying to solve:

const arr1 = [
  [1637837518000, 1.7],
  [1637837519000, 0.1],
  [1637837520000, 1.3],
  [1637837521000, 6.4],
  [1637837522000, 2.2],
  [1637837523000, 2.1]
];
const arr2 = [
  [1637837517000, 600.32],
  [1637837520000, 578.98],
  [1637837523000, 612.76]
];
const arr3 = [
  [1637837518000, 45.3],
  [1637837520000, 34.8],
  [1637837522000, 40.0],
  [1637837524000, 41.5]
];

And the desired result would be:

[
  [1637837517000, null, 600.32, null],
  [1637837518000, 1.7,  null,   45.3],
  [1637837519000, 0.1,  null,   null],
  [1637837520000, 1.3,  578.98, 34.8],
  [1637837521000, 6.4,  null,   null],
  [1637837522000, 2.2,  null,   40.0],
  [1637837523000, 2.1,  612.76, null],
  [1637837524000, null, null,   41.5]
]

There is no need for interpolation, so if a timestamp does not exist in any data array, there need not be any entry in the result array of that timestamp.

CodePudding user response:

The below should solve the problem resonably efficiently:

const arr1 = [
  [1637837518000, 1.7],
  [1637837519000, 0.1],
  [1637837520000, 1.3],
  [1637837521000, 6.4],
  [1637837522000, 2.2],
  [1637837523000, 2.1]
];
const arr2 = [
  [1637837517000, 600.32],
  [1637837520000, 578.98],
  [1637837523000, 612.76]
];
const arr3 = [
  [1637837518000, 45.3],
  [1637837520000, 34.8],
  [1637837522000, 40.0],
  [1637837524000, 41.5]
];

function concat(...arrs){
  const result = {};
  for(var i=0;i<arrs.length;i  ){
    for(let [ts,val] of arrs[i]){
      result[ts] = result[ts] || new Array(arrs.length   1).fill(null);
      result[ts][0] = ts;
      result[ts][i 1] = val;
    }     
  }
  return Object.values(result).sort( (a,b) => a[0] - b[0]);
}

console.log(concat(arr1,arr2,arr3));
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

i hope that might help doesn't look so beautiful

but it does the job even if entered 10000 arguments

note : the order of the arguments matter

function concatTimeZones() {
    const allTimeZones = []
    var baseArray = Array.apply(null, Array(arguments.length   1)).map(function () { return null });

    for (let element in arguments) {
        for (let timezone in arguments[element]) {
            let item = arguments[element][timezone];
            let newItem = [...baseArray]
            newItem[0] = item[0];
            newItem[Number(element)   1] = item[1];
            allTimeZones.push(newItem);
        }
    }
    let sorted = allTimeZones.sort(function (a, b) {
        return a[0] - b[0]
    })
    return sorted
}
concatTimeZones(arr1, arr2, arr3, arr4)
  • Related