How can you eliminate the first elements of two or more arrays of objects until all of their first elements match based on a specific field?

My Typescript code includes a Map object called `stat_map` defined as

const stat_map: Map<string, IMonthlyStat[]> = new Map();

The interface IMonthlyStat is structured as shown below (Note that there are more fields in reality)

export interface IMonthlyStat {
  month: string;
  value: number;
}

The issue arises when the values within the Map, specifically the IMonthlyStat arrays, contain different month values due to data added at various times.

The format of the month field is '2021-02-01T00:00:00.000 UTC'.

I am looking for the most efficient way to standardize all IMonthlyStat arrays by removing initial elements so they all start with the same month string.

For example, if we have two IMonthlyStat arrays like

[
    {month: '2021-02-01T00:00:00.000 UTC', value: 6}, 
    {month: '2021-03-01T00:00:00.000 UTC', value: 8}, 
    {month: '2021-04-01T00:00:00.000 UTC', value: 10}
]

and

[
    {month: '2021-03-01T00:00:00.000 UTC', value: 7}, 
    {month: '2021-04-01T00:00:00.000 UTC', value: 9}
]

How can I achieve results like this:

[
    {month: '2021-03-01T00:00:00.000 UTC', value: 8}, 
    {month: '2021-04-01T00:00:00.000 UTC', value: 10}
]

and

[
     {month: '2021-03-01T00:00:00.000 UTC', value: 7}, 
     {month: '2021-04-01T00:00:00.000 UTC', value: 9}
]

Answer №1

In case you're interested, I have a function below that adjusts an array of arrays so that all arrays begin with the same element, assuming there is at least one common element among them. The comparison of elements is based on a specified key function:

key(A) == key(B) -> A equals B

function alignBy(arrays, keyFunction) {
    for (let item of arrays[0]) {
        let indexes = arrays.map(array => 
            array.findIndex(element => keyFunction(item) === keyFunction(element)))
        if (indexes.every(i => i >= 0))
            return arrays.map((array, index) => array.slice(indexes[index]))
    }
}

//

arrayA = [
    {month: '1', value: 6},
    {month: '2', value: 8},
    {month: '3', value: 10},
    {month: '5', value: 9},
]

arrayB = [
    {month: '2', value: 7},
    {month: '3', value: 9},
    {month: '4', value: 9},
    {month: '6', value: 9},
]

arrayC = [
    {month: '3', value: 7},
    {month: '3', value: 9},
    {month: '4', value: 9},
    {month: '5', value: 9},
]


result = alignBy([arrayA, arrayB, arrayC], x => x.month)
for (item of result) {console.log(...item); console.log('----')}

Answer №2

const MonthlyData1= [
    {month: '2021-02-01T00:00:00.000 UTC', value: 6}, 
    {month: '2021-03-01T00:00:00.000 UTC', value: 8}, 
    {month: '2021-04-01T00:00:00.000 UTC', value: 10}
]
 
const MonthlyData2= [
    {month: '2021-03-01T00:00:00.000 UTC', value: 7}, 
    {month: '2021-04-01T00:00:00.000 UTC', value: 9}
]

function compareAndRemoveDates(data1, data2){

if (data1 === data2){
    return {
        finalData1: data1,
        finalData2: data2
    }
}
 
const initialDateArray1 = data1[0].month.split('T')[0].split('-')
const initialDateArray2 = data2[0].month.split('T')[0].split('-')

const utcDate1 = new Date(initialDateArray1[0], initialDateArray1[1], initialDateArray1[2]);
const utcDate2 = new Date(initialDateArray2[0], initialDateArray2[1], initialDateArray2[2]);

const dateDiff = utcDate1 < utcDate2 // If true we need to remove Dates in array1 else we need to remove Dates in array2

if(dateDiff){
    return removeDates(data1, data2)
} else {
    return removeDates(data2, data1)
}
}


function removeDates(mutableArr, inmutableArr){
    const initialMonthInmutableArr = inmutableArr[0].month

    while(mutableArr[0].month !== initialMonthInmutableArr){
        mutableArr.shift()
    }

    return {
        finalData1: mutableArr,
        finalData2: inmutableArr
    }    
}

const { finalData1, finalData2 } = compareAndRemoveDates(MonthlyData1, MonthlyData2)

console.log(finalData1)

console.log(finalData2)

/*
[
  { month: '2021-03-01T00:00:00.000 UTC', value: 8 },
  { month: '2021-04-01T00:00:00.000 UTC', value: 10 }
]
[
  { month: '2021-03-01T00:00:00.000 UTC', value: 7 },
  { month: '2021-04-01T00:00:00.000 UTC', value: 9 }
]
*/

Answer №3

Method 1 using array.filter() and array.some()

If I understand correctly, you want to find the common elements between two arrays based on dates.

You can achieve this by using array.filter() and array.some().

You can combine these functions to find elements in array1 where the .month value also exists in array2. For your case, you can repeat this process for both arrays.

The main difference from your original request is that it searches the entire array instead of just looking for the first match, so processing time may be impacted by the array size.

let intersection = array1.filter(x => array2.some(y=> x.month === y.month));

Try running this snippet for a simple demo:

let array1 = [
    {month: '2021-02-01T00:00:00.000 UTC', value: 6},
    {month: '2021-03-01T00:00:00.000 UTC', value: 8},
    {month: '2021-04-01T00:00:00.000 UTC', value: 10}
];

let array2 = [
    {month: '2021-03-01T00:00:00.000 UTC', value: 7},
    {month: '2021-04-01T00:00:00.000 UTC', value: 9}
];

let intersection = array1.filter(x => array2.some(y=> x.month === y.month));
let intersection2 = array2.filter(x => array1.some(y=> x.month === y.month));

console.log(intersection);
console.log(intersection2);

Method 2 with findIndex()

If your arrays are always sorted by month and you're only interested in finding the first matching element, you can follow these steps:

  1. Compare the first items of both arrays to determine the latest month
  2. Use findIndex() to locate the index of that month in each array
  3. Split the arrays based on those indices

Here's a straightforward implementation with slightly more code than the first method but should be more efficient as it only checks the initial item in each array and performs a splice operation:

let array1 = [
    {month: '2021-02-01T00:00:00.000 UTC', value: 6},
    {month: '2021-03-01T00:00:00.000 UTC', value: 8},
    {month: '2021-04-01T00:00:00.000 UTC', value: 10}
];

let array2 = [
    {month: '2021-03-01T00:00:00.000 UTC', value: 7},
    {month: '2021-04-01T00:00:00.000 UTC', value: 9}
];

processedArray1 = [];
processedArray2 = [];

// Find the latest initial month from both arrays
const latestFirstMonth = array1[0].month >= array2[0].month ? array1[0].month : array2[0].month;

// Find the indices of the latest month in each array (since it will be 0 for the array with the latest month initially)
const array1Index = array1.findIndex(element => element.month >= latestFirstMonth);
const array2Index = array2.findIndex(element => element.month >= latestFirstMonth);

// Split the arrays based on these indices
processedArray1 = array1.splice(array1Index);
processedArray2 = array2.splice(array2Index);

console.log(processedArray1);
console.log(processedArray2);

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

Arrangement of Bootstrap card components

Each card contains dynamic content fetched from the backend. <div *ngFor="let cardData of dataArray"> <div class="card-header"> <div [innerHtml]="cardData.headerContent"></div> </div> <d ...

A malfunction report stemming from an HTTP error code while using react.js/javascript

In my react.js application, I have a Component that displays an error code. It currently looks like this: https://i.stack.imgur.com/2usiy.png Now, in addition to displaying just the code, I also want to show the reason for the error. Similar to how this ...

"Getting an 'Undefined index' error while accessing a JavaScript variable in PHP

Every row in my table contains an Edit button. I managed to fetch the row number by clicking on the Edit button using JavaScript, but I am unsure how to do it in PHP. My attempt to pass the variable from JS to PHP resulted in an error: Undefined index ...

Store the visible image location in memory to be used across various sections

I'm currently developing a website with a scrolling background image feature. However, whenever I navigate to another page on the site, the animation restarts from the beginning. Is there a way to cache the position so that the animation continues sea ...

Dealing with an unexpected token error in JSON? Learn how to properly handle removing special characters like quotation marks and line breaks to

After receiving a JSON response from the server during page load, I successfully populate it on the page using Handlebars.js. However, I am facing difficulties in storing this JSON object in a JavaScript object. Here is what I tried: var jsObject = "{{o ...

Dealing with a throw er; uncaught 'err' event while configuring a server with nodemon

I am currently in the process of setting up my local server using node.js and nodemon. Initially, everything runs smoothly on localhost, but as soon as I refresh the page or navigate to another page, the server crashes with an 'unhandled error event&a ...

Activate single elements one at a time

If you want to understand the question better, take a look at my code on jsfiddle. Each Div contains only one link. When you click on the link, it sets the Div to active and shows a hidden Div within it. Clicking the link again toggles the active style an ...

Creating an axios URL using Vue data results in receiving the value of undefined

I'm currently experimenting with axios to retrieve data from openweathermap. I've been working on constructing the URL by utilizing various methods to extract latitude and longitude from the user's browser, followed by a function call to pie ...

Load Angular component on demand with necessary dependencies

Searching for an elegant solution (without resorting to private APIs) to create a widget-style dashboard. The goal is to dynamically load components based on user role. Is there a way to import a component and its dependencies included in the component&ap ...

Adapting npm scripts with Node.js based on the current context

Can you set up package.json to execute a different npm start script depending on the context? For instance, I want to run DEBUG=http nodemon app.js during development. However, I prefer to run node app.js in production. ...

The duration from when the Ajax request is sent to when the response is received results in

Has anyone experienced strange results when measuring the time between sending and receiving an ajax request? Sometimes I get negative values. Can someone shed light on this peculiar behavior? var before = 0; var after = 0; $.ajax({ url: 'data.ph ...

Unlimited highway CSS3 motion

I have come across a stunning 2D Highway background image that I plan to use for my mobile racing game project which involves JS and CSS3. The image can be found at this link. My goal is to create an animation of the road in order to give players the illu ...

What is the unit testing framework for TypeScript/JavaScript that closely resembles the API of JUnit?

I am in the process of transferring a large number of JUnit tests to test TypeScript code on Node.js. While I understand that annotations are still an experimental feature in TypeScript/JavaScript, my goal is to utilize the familiar @Before, @Test, and @Af ...

A guide on obtaining the pixel dimensions of a ThreeJS mesh object: determining its visible width and height

I am currently grappling with the task of determining the visible view width and height of a ThreeJS mesh object in pixel units. In the image provided below, you can observe objects suspended in 3D space. Upon clicking the mouse, I need to be able to disc ...

Creating a multipart/form-data POST request in Angular2 and performing validation on the input type File

I am working on sending an image (base64) via a POST request and waiting for the response. The POST request should have a Content-Type of multipart/form-data, and the image itself should be of type image/jpg. This is what the POST request should look like ...

I am seeking a way to conceal list elements according to a specified string input using JavaScript

Looking at the list items inside this div: <div class="container"> <h2>Vanishing Act Game</h2> <div> <li class="list-group-item go" id="item">Door#1</li> <li class="list-group-item go" id="it ...

Jquery refuses to load

Hey everyone! I'm currently working on an HTML file for my Angular 2 course. After setting up the dependencies and downloading them with npm, I encountered an error when trying to run the app... The error message I received was: file:///Users/Rocky/A ...

Can the w regular expression pattern be modified to include special characters like é? If not, what other options are available?

Imagine having a regular expression that appears as follows: \w+ In this case, the string "helloworld" would be accepted: helloworld However, "héllowörld" would not pass the test: héllowörld The regex will stop at é (and also break atö) ev ...

Creating animated effects through Javascript and CSS triggered by user events

As a beginner in javascript and CSS, I am experimenting with creating a simple animation that adjusts the transparency of an image when triggered by an event. However, I am facing an issue where the animation only works every other time the function is cal ...

Getting the dimensions of an image when clicking on a link

Trying to retrieve width and height of an image from this link. <a id="CloudThumb_id_1" class="cloud-zoom-gallery" rel="useZoom: 'zoom1', smallImage: 'http://www.example.com/598441_l2.jpg'" onclick="return theFunction();" href="http ...