Ways to obtain a combined total array from three sets of two-dimensional arrays

I have a total of 3 arrays containing two-dimensional data which represent series data for plotting lines on a graph. Each array consists of timestamps as keys.

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 am looking to plot an additional line series that represents the cumulative total of all three arrays' values by timestamp. If a timestamp is missing in any of the arrays, I would like to 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]
]

Although I attempted to do this, there are some incorrect values due to missing timestamps in one of the arrays.

My 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("Current 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();

Can this be achieved successfully?

Answer №1

Your code is currently containing the following lines:

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

However, this assignment will not work because arr1[-1] is not defined.

Subsequently, when you perform:

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

...you are creating an array that lacks the ability to utilize default values (from a preceding index) if any of the three arrays have a "missing" timestamp.

I recommend the following approach:

  1. Gather all unique timestamps (from all arrays) into a Map and assign empty arrays to each of those keys initially.
  2. Add the timestamps from the original arrays to their respective arrays in the map.
  3. Retrieve a sorted list of entries from the map.
  4. Fill in the "gaps" by carrying forward values to the next array when the corresponding slot is undefined. Simultaneously, accumulate these values for the final output.

Below is an implementation example:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for sending a form with the <button type="submit"> element

I created a login form and initially used <button type="submit">, but unfortunately, it was not functioning as expected. However, when I switched to using <input type="submit">, the form submission worked perfectly. Is there a JavaScript method ...

Troubleshooting Next.js and NextAuth.js Authentication Redirect Issue

I am experiencing a problem with authentication in my Next.js application using NextAuth.js. The issue specifically pertains to the redirection after successful login. Here is an overview of my setup: NextAuth.js Configuration (app/api/auth/[...nextauth.js ...

Direct your attention to alternative data sources following the selection of an item in the typeahead search feature

Having some trouble with angular-ui bootstrap: I am using 2 input elements: <input type="text" ng-model="selected" uib-typeahead="state for state in states | filter:$viewValue | limitTo:8" typeahead-on-select="focusSuccessive($item, $model, $label, $ev ...

Mobile Chrome allows users to utilize the IFrame player API for enhanced video

Currently, I am working on creating a mobile website where I plan to include some YouTube videos using the IFrame player API (https://developers.google.com/youtube/iframe_api_reference). My main goal is to have the video start playing only after the user ...

Unable to include an element into a vacant array becomes the root of discussion on contrasts between inserting, appending, and concatenating

Question: Given a matrix mat of size 3 x 3, find all the even numbers located in each row where the cumulative sum at the end is greater than or equal to 150. [[ 51 21 14] [ 56 85 22] [ 99 666 230]] Answer: [ 56 22 666 230] import numpy as np m ...

Troubleshooting issues with logging out in AngularJS

After attempting to logout of my current session, I realized that the logout feature is not working. Below is the code I have used: view <a ui-sref="logout"> <i class="fa fa-sign-out"></i> Log out </a> config.js $stateProvide ...

Tips for sending information to afterClosed() within Angular Material Dialog on Angular 6

I'm struggling to transfer data from a Dialog back to the component that opened it. Here's a simplified example: test.component.ts import { xDialogComponent } from './../x-dialog/x-dialog.component'; import { xFilter } from './ ...

Python Selenium code is encountering a "Element not found" exception

I am facing difficulty in finding the specific element on the webpage. Even though I can visually see it on the webpage, I am unable to locate it programmatically. I have tried using explicit waits and Xpath to pinpoint the element without success. Despite ...

Whenever I press a button, my desire is for each picture to seamlessly reposition itself in the exact same spot on the screen

Having some issues with my code. When I click a button, the plan is for the pictures to change one by one to simulate a traffic light sequence. However, when I run the code, all the pictures appear at once without any effect from the button. Any help in ac ...

JQuery appended Bootstrap Modal to Body, but it refuses to close

After going through the process of appending the modal to the body and getting the text box working, I encountered an issue when trying to close it on the AJAX success event - none of my attempted solutions seem to be effective. var id; var refundAmount ...

Pause and anticipate a request in MongoDB

I am facing an issue with my Typescript async method used to query a MongoDB database using the nodejs driver. The compiler seems to be indicating that the "await" before "myConnectedClient" has no effect on the type of this expression. This has left me co ...

What is the process for retrieving data from multiple tables within a database using Node.js, MySQL, and Express.js?

Can someone help me pinpoint the issue? I am trying to retrieve data from different MySQL tables using separate queries, specifically in gestionEntreprise.ejs: <tbody> <tr> <% data1.forEach(entry => { %> &l ...

Tips for efficiently handling navigation re-rendering on a Single Page Application using Vue.js

I am currently in the process of developing a Single Page Application using Vue.js. The structure involves having a template in App.vue which includes a navigation bar followed by a router-view component. When a user attempts to log in, a modal window appe ...

Opening a fresh window with HTML content extracted from the existing page

Is there a way to open a new window and transfer some of the HTML content from the original page to the new window? For example: $("div#foo").click( function(){ var copyHTML = $("table.bar").html(); window.open(''); // how can we ...

Discovering the best way to display information in two separate cards using the JSON response in Next.js

I recently encountered a JSON response that sometimes contains an empty key labeled "image". This data is being fetched using getServerSideProps(): [ { "date": "03/11/2022, 18:45:24", "description": "Want to know more about simping and ...

Determine the Button's State by Monitoring Changes in the TextBox Text

I have been tasked with developing a web application for my company. The main components of the application are a button and a textbox. My goal is to allow users to input a value into the textbox, which will then be processed when they click on the button ...

Traverse through an array of pictures and add the data to a Bootstrap placeholder within HTML markup

In my quest to create a function that populates placeholders in my HTML with images from an array, I am encountering a problem. Instead of assigning each image index to its corresponding placeholder index, the entire array of images is being placed in ever ...

Managing the invocation of a promise multiple times in AngularJS, and handling some specific exceptions

After previously asking a question on handling promises multiple times in AngularJS (AngularJS handle calling promise multiple times), I am facing a new challenge. This time, I need to retrieve a list of cities, but encounter an exception. Similar to how ...

Tips for preventing a promise from being executed more than once within an observable while being subscribed to a BehaviorSubject

I've defined a class called Store with the following structure: import { BehaviorSubject, Observable } from 'rxjs' export abstract class Store<T> { private state: BehaviorSubject<T> = new BehaviorSubject((undefined as unknown ...

What are the steps to effectively utilize the $filter('filter') function when filtering multiple columns with OR as the condition?

In my AngularJs Application, I have a collection of customers. var customers = [ { "Name": "Alfreds Futterkiste", "City": "Berlin", "Country": "Germany" }, { "Name": "Ana Trujillo Emparedados y helados", ...