What is the best way to combine two arrays by sorting them according to their respective years?

I have two separate arrays: one containing values by year and order ID, and the other with different data. My goal is to combine them into a single array based on the year.

let array1 = [{orderId: 1, year: 2020, value: 15}, 
              {orderId: 1, year: 2021, value: 20}, 
              {orderId: 1, year: 2022, value: 25},
              {orderId: 2, year: 2020, value: 30}, 
              {orderId: 2, year: 2021, value: 35}, 
              {orderId: 2, year: 2022, value: 40}]
let array2 = [{id: 1, year: 2020, value: 10}, 
              {id: 2, year: 2020, value: 20}, 
              {id: 3, year: 2020, value: 30},
              {id: 1, year: 2021, value: 10}, 
              {id: 2, year: 2021, value: 20}, 
              {id: 3, year: 2021, value: 30}, 
              {id: 1, year: 2022, value: 10}, 
              {id: 2, year: 2022, value: 20}, 
              {id: 3, year: 2022, value: 30}]

The desired end result would be:

finalArray = [{year: 2020, array1Values: [15, 30], array2Values: [10, 20, 30]},
              {year: 2021, array1Values: [20, 35], array2Values: [10, 20, 30]},
              {year: 2022, array1Values: [25, 40], array2Values: [10, 20, 30}]]

This involves iterating through the years, extracting the corresponding values from array1 (2 values for each orderId), and then array2 (3 values for each Id).

I am uncertain where to begin with this. At the moment, my plan is to create an object like this:

let myObject = {
    year: 0,
    array1Values = [],
    array2Values = []
}

My approach would then be to loop through array1, instantiate myObject, and set the year. I can check if the next element in array1 exists and whether the year is greater than the current element's year before setting it.

Within that loop, I would filter array1 based on the year, push those values into array1Values, sort array2 by id, filter it based on year, and push those values into array2Values. Once completed, I can push myObject into finalArray. Is there a more efficient way to achieve this?

Answer №1

let data1 = [{orderId: 1, year: 2020, value: 15}, 
              {orderId: 1, year: 2021, value: 20}, 
              {orderId: 1, year: 2022, value: 25},
              {orderId: 2, year: 2020, value: 30}, 
              {orderId: 2, year: 2021, value: 35}, 
              {orderId: 2, year: 2022, value: 40}]
let data2 = [{id: 1, year: 2020, value: 10}, 
              {id: 2, year: 2020, value: 20}, 
              {id: 3, year: 2020, value: 30},
              {id: 1, year: 2021, value: 10}, 
              {id: 2, year: 2021, value: 20}, 
              {id: 3, year: 2021, value: 30}, 
              {id: 1, year: 2022, value: 10}, 
              {id: 2, year: 2022, value: 20}, 
              {id: 3, year: 2022, value: 30}]
              
const finalResult = [...data1, ...data2].reduce((acc, {year, value}) => {
    const index = acc.findIndex(e => e.year === year)
    if(index === -1) {
      return [
        ...acc,
        {year, values: [value]}
       ]
    } else {
      acc[index].values.push(value);
      return acc;
    }
  }, []);
  
console.log(finalResult);

Answer №2

Consider using this approach:

View the Live Demo

  constructor() {
    var groupedData1 = this.groupByKey(this.array1, "year");

    Object.keys(groupedData1).forEach(item => {
      let value = groupedData1[item].map(x => x.value).join(", ");
      this.finalArray.push({
        year: item + ", " + value
      });
    });

    var groupedData2 = this.groupByKey(this.array2, "year");

    Object.keys(groupedData2).forEach(item => {
      let value = groupedData2[item].map(x => x.value).join(", ");
      let keyData = this.finalArray.find(x => x.year.includes(item));
      keyData.year += ", " + value;
      console.log(value);
    });
  }


  groupByKey(data, key) {
    return data.reduce(function(rv, x) {
      (rv[x[key]] = rv[x[key]] || []).push(x);
      return rv;
    }, {});
  }

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

"Efficient ways to calculate the total sum of an array of objects based on a specific property

I currently have a straightforward method that calculates the total sum of an object array based on one of the properties. const calculateSum = <T extends object, K extends keyof T>(array: T[], property : K) : number =>{ let total = 0; if ( ...

Guide to manually triggering a re-render of a component in Angular 2

While working with ng Smarttable, I encountered a situation where I needed to change the datasource array through an event, specifically by altering an ID within the array. Strangely, Angular did not detect these changes until I interacted with the page by ...

Angular - Implementing MatBottomSheet within a parent element for a seamless user experience

I'm attempting to display a material bottom sheet inside a specific div container, but by default it always opens at the end of the document body. After reviewing the documentation, I understand that I need to utilize the viewContainerRef, however, I ...

Exploring the power of RxJs through chaining observers

In my Angular application, I am utilizing Observables to set up a WebSocket service. Currently, I have the following implementation: readwrite(commands: command[]) : Observable<response[]>{ const observable = new Observable((observer)=>{ ...

Tips for isolating shared attributes within MUI Data Grid column configurations

Currently, I am developing a ReactJS Typescript Application using MUI as my component library. My goal is to create a comprehensive CRUD Datagrid similar to the MUI Datagrid component. In the example provided, many columns share common properties. To effic ...

What is the best way to use two distinct CSS styles for mat-form-field across multiple pages?

On one of my pages, I have a mat-form-field: <mat-form-field class="form-control-full-width"> <input type="text" matInput placeholder="First Name" formControlName="firstNameFC" required> <mat-error *ngIf="hasNewUserErro ...

Tips on extracting specified attributes within the overlapping area of a generic category and a specific classification

I created an HOC that accepts a withPaper prop but doesn't forward it to the component it will render. import React, { ComponentType, FC } from "react"; import { Paper } from "@material-ui/core"; interface WithOptionalPaperProps { withPaper?: bool ...

Is there a way to transform a component into a microservice in Angular?

I am in the process of developing an Angular application that utilizes various microservices. I have been searching for tutorials on how to effectively convert a component into a microservice, but have not found any clear guidance. I attempted to follow th ...

Is there a way to search through an array of object arrays in JavaScript for a specific key/value pair using lodash or any other function?

I am faced with a task involving an array of objects. Each object has a key that needs to be used to search through sets of arrays containing similar objects. The goal is to determine if all the arrays contain the same value for a specific key in my object ...

There is a compatibility issue between the module and the engine "node" in this instance

Upon running the command npx create-react-app my-awesome-react-app --template typescript, I encountered the following yarn error: Error [email protected]: The engine "node" is incompatible with this module. Expected version "^6 || ^7 || ^8 || ^9 || ^10 || ...

How to Use an Object Created from a Different Class in TypeScript

Scenario In the development process, I am using an auth.service.ts. This service is responsible for fetching user information from the database upon login. The retrieved data is then used to create a new user object. Here is a snippet of the code: user: ...

Utilize the ref attribute when working with Material UI InputLabel components

Is there a way to access the ref parameter of an InputLabel from the @material-ui/core library using TypeScript? When I attempt to do so, the following code produces an error related to ref: TS2769: No overload matches this call. export class ComboBo ...

The @output decorator in Angular5 enables communication between child and

Hello fellow learners, I am currently diving into the world of Angular and recently stumbled upon the @output decorators in angular. Despite my best efforts to research the topic, I find myself struggling to fully grasp this concept. Here's a snippet ...

How can I validate a method for formGroup in Angular 2?

Below is a form I am working with: this.changePasswordForm = this.formBuilder.group({ 'passwordNew': ['', ValidationService.passwordValidator], matchingPasswords('passwordNew', 'passwordNewConfirmation')(this) ...

Implementing CSS Pre-loading in an Angular Application with Webpack and Heroku

My current setup involves an Angular application (v4.0.1) with webpack deployed on Heroku. I have a loading spinner in place to show while the app is loading, and it works well locally. However, when deployed on Heroku, the loading spinner (specifically th ...

What could be causing the promise in Angular 8 to return an undefined value, even though it was correctly logged just before it was resolved?

MODIFY I checked to see if the script is entering the addHousehold() if condition here: addHouseholdPromise.then((res) => { console.log("Promise HH: "+res) if (res != "add_hh_fail") { console.log("success: "+res) return res ...

When the disable attribute in ngx-chips is set to false, the tag-input-dropdown will be shown

While utilizing ngx-chips, I encountered a problem where a button was disabling the input and causing the tag-input-dropdown to display as if the user had clicked on the input field. You can see a working demo of this issue on stackblitz In an attempt to ...

While attempting to reinstall the admob-free plugin via npm, I encountered an error stating that it was missing a package.json file

While developing an app using Ionic, I encountered an issue with the AdMob plugin not being installed correctly. Trying to resolve this, I attempted to reinstall the plugin multiple times but kept running into errors. Seeking help from various threads, I ...

Stop MatDialog instance from destroying

In my application, I have a button that triggers the opening of a component in MatDialog. This component makes API calls and is destroyed when the MatDialog is closed. However, each time I open the MatDialog for the second time by clicking the button agai ...

The Angular 2 project, built with the CLI tool, has been transformed into an npm

We have a project in the works that involves creating a large application using angular 2. This project consists of one main parent angular 2 application and three separate sub-child applications that are unrelated to each other. Each of these sub-child ...