Create a function that takes two arrays as input and assigns variables to store the matching and non-matching elements between the two arrays

Definition of Interface -

interface I {
  name: string;
  age: number;
  size?: string;
}

Arrays Initialization -

let firstArrayMatches: I[] = [];
let firstArrayUnmatches: I[] = [];

let secondArrayMatches: I[] = [];
let secondArrayUnmatches: I[] = [];

Initial Values for First Array -

const firstArray: I[] = [
  {
    name: 'daniel',
    age: 30
  },
  {
    name: 'tamir',
    age: 30
  }
]

Initial Values for Second Array -

const secondArray: I[] = [
  {
    name: 'daniel',
    age: 30,
    size: 'm'
  },
  {
    name: 'ariel',
    age: 28,
    size: 'm'
  }
]

Mapping the Elements in secondArray to return a string[] -

const secondArrayIndexes = secondArray.map(({ name, age }) => name  + '/' + age);

Iterate through the firstArray, if there is a match push the object into firstArrayMatches and push ...secondArray.splice(match, 1) into secondArrayMatches. If no match, push the object into firstArrayUnmatches and assign the remaining elements in the second array to secondArrayUnmatches.

for (const o of firstArray) {
  const match = secondArrayIndexes.indexOf(o.name + '/' + o.age);

  if (match >= 0) {
    firstArrayMatches.push(o);
    secondArrayMatches.push(...secondArray.splice(match, 1));
  } else {
    firstArrayUnmatches.push(o);
  }
}
secondArrayUnmatches = secondArray;

Output Results -

console.log('First Matching Objects: '+ JSON.stringify(firstArrayMatches))
console.log('First Unmatched Objects: '+ JSON.stringify(firstArrayUnmatches))

console.log('Second Matching Objects: '+ JSON.stringify(secondArrayMatches))
console.log('Second Unmatched Objects: '+ JSON.stringify(secondArrayUnmatches))

Expected Output -

First Matching Objects:

[{"name":"daniel","age":30,"size":"m"}]

First Unmatched Objects: [{"name":"tamir","age":30}]
Second Matching Objects:
[{"name":"daniel","age":30,"size":"m"}]

Second Unmatched Objects:
[{"name":"ariel","age":28,"size":"m"}]

The function should transfer properties from the second array to the first array if there is a match.

Answer №1

It is often not advisable to mutate arrays directly. Instead, consider filtering out elements you do not need:

function compareItems(i1: Item, i2: Item) {
    return i1.name === i2.name && i1.age === i1.age
}

const matchingItemsFromFirstArray = firstArray.map((item1)=> secondArray.find((item2) => compareItems(item1, item2))).filter((item) => item)
const unmatchedItemsInFirstArray = firstArray.filter((item1) => !secondArray.some((item2) => compareItems(item1, item2)))

const matchingItemsFromSecondArray = secondArray.filter((item1) => firstArray.some((item2) => compareItems(item1, item2)))
const unmatchedItemsInSecondArray = secondArray.filter((item1) => !firstArray.some((item2) => compareItems(item1, item2)))

You can also achieve this using reduce method:

firstArray.reduce((acc: { match: Item[], unmatch: Item[] }, item1: Item) => {
    const item2 = secondArray.find((item2) => compareItems(item1, item2)) 
    item2 ? acc.match.push(item2) : acc.unmatch.push(item1);
    return acc;
}, { match: [], unmatch: [] })

Check it out in Playground.

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

Customize Swiper js: How to adjust the Gap Size Between Slides using rem, em, or %?

Is there a way to adjust the spacing between slides in Swiper js using relative units such as 2rem? The entire page is designed with relative units. All measurements are set in rem, which adjusts based on the viewport size for optimal adaptability. For i ...

Overlaying images with cropped elements

When uploading an image on a webpage, I want to display a preview of the image. I am looking to create an overlay that showcases the image in a rectangle at the center, surrounded by a semi-transparent background outside the rectangle. Something resemblin ...

How can I send parameters to an HTML file using Node.js?

In my current code res.sendfile('./home.html',{user:req.user}), I need to figure out a way to access the user parameter directly in the HTML file without relying on a template engine. Can anyone suggest how this can be achieved? ...

Tips for handling various mandatory fields for two different user roles within a unified userModel.ts file on a Next.js and MongoDB user registration API platform

Could you please review my code and provide any suggestions for improvement? I have two types of user roles, candidate and business, each with multiple unique fields. My goal is to consolidate all these fields into one userModel.ts file. import mongoose ...

The angular build prod function was expecting 2 arguments, but only 1 argument was provided

When I serve my Angular app normally, everything works fine. But when I try to serve it in production mode, I encounter this error that is leaving me quite perplexed. //error on build: Expected 2 arguments, but got 1. <ion-col class="ion-no-paddin ...

React DataGrid fails to refresh when state changes

Currently, I am in the process of developing a link tree using the Datagrid Component provided by MaterialUI. While data can be successfully displayed, I encounter an issue when attempting to add a new entry. The problem lies in the fact that despite cha ...

What is the most efficient method for sending query parameters through a URL in Vue.js with Axios?

My goal is to use Axios upon page load to retrieve a JSON object from the base URL. When a button is clicked, I want to append query parameters to the URL and fetch a different JSON object. For example, if the base URL is 'test.com', clicking the ...

The argument passed cannot be assigned to the parameter required

Currently, I am in the process of transitioning an existing React project from JavaScript to TypeScript. One function in particular that I am working on is shown below: const isSad = async (value: string) => { return await fetch(process.env.REACT_AP ...

Troubleshooting: MySQL Array fetch functionality malfunctioning

My current code utilizes a WHILE loop to generate 4 tabs with titles retrieved from the database. Each tab is assigned a tab_id (1,2,3,4) in the database. The issue I am facing is that when the code runs, all four rows display the tab_id as "1" even thoug ...

Tips for incorporating a callBack function when the screen changes in react-native:

Is there a way to implement a callback function that executes whenever the screen changes, such as moving from the home screen to the about screen? Situation I would like to create a global stack that triggers a callback function whenever any navigation o ...

What sets apart utilizing a constructor versus state = {} for defining state in a react component?

There are two ways to declare state in a class component as shown below: class App extends Component { constructor(props) { super(props); this.state = { name: 'John' } } render() { return ...

Utilizing directive scope variables to generate dynamic templates

Looking for a solution to dynamically render forms with various controls based on a specific Type value specified in a JSON object. The form will be created based on user input, so the necessary question types may vary. While we will define the types, they ...

Organizing dates with Google Apps Script in a two-column format

I am trying to combine 2 cells in apps script to generate a single date for adding an event to my calendar. function ConcatenateDateCells () { var spreadsheet = SpreadsheetApp.getActive(); var sheet1 = spreadsheet.getSheetByName("TABLEAU DE BORD") ...

Is there a way to capture real-time console output in an ExpressJS application while a script is running?

I'm facing a challenge in integrating the output of a bash script into an ExpressJS application to then send the data to a client. To address this, I have developed a simplified version of my actual script for testing purposes. My goal is to capture a ...

Connecting Vue.JS page to my existing HTML page: A step-by-step guide

While developing my website, I faced a challenge with the structure. The home page was built using traditional HTML/CSS, while the other pages were created in Vue.js. Is there a method to connect these two different types of files? For instance, can I inc ...

How does JavaScript function syntax differ in Next.js and JSX?

I'm in the process of creating a function that allows users to select different sizes. It currently works fine with just JavaScript and HTML, but I'm encountering an error when using it in Next.js. Can someone confirm if my syntax for the JavaScr ...

The expression "routerlink" in Angular 9 is not recognized,

Currently, I am in the process of developing an Angular 9 application and have encountered two challenging issues. Firstly, as I navigate through the routes using the navbar, I notice an error message in the console stating "Syntax error, unrecognized exp ...

Unbearably long wait for Ajax request

For some reason, my Javascript code is running incredibly slow, taking up to five minutes to complete. Sometimes after refreshing the page, certain requests haven't even been processed yet. I've already tried setting async:true, hoping it would ...

Assign the value of a JSON key/value pair to the following key

I have a json file with data structured like this (showing one row as an example): "description 1": { "year0": "49", "year1": "48", "year2": "876786", "year3": "1234" }, Using PHP, I want to rearrange the values so that the value for year0 becom ...

Implement a redux-form within a react-bootstrap modal

I am facing a challenge with incorporating a multipage 'redux-form' form into a react-bootstrap modal. My goal is to have the form displayed within the modal overlay when the modal is opened. How can this be achieved? The code below is producin ...