Combining arrays by a shared property in JavaScript

My goal is to merge data from two arrays based on the userId. The current solution I have only works efficiently with small datasets, but it becomes impractical with larger arrays due to the excessive use of the filter method. Does anyone have a more efficient approach in mind?

PS: I'm using > 0 ? because sometimes one of the properties is empty.

const data01 = [
      { userId: 0, motorcycles: 'motorcycle01', cars: 'car01' },
      { userId: 1, motorcycles: 'motorcycle02', cars: 'car02' },
      { userId: 2, cars: 'car03' },
      { userId: 3, motorcycles: 'motorcycle04' },
    ]


    items.forEach(
      a =>
      (
        a.motorcylces = data01.filter(b => b.userId === a.userId).length > 0 ? data01.filter(b => b.userId === a.userId)[0].motorcylces : null,
        a.cars = data01.filter(b => b.userId === a.userId).length > 0 ? data01.filter(b => b.userId === a.userId)[0].cars : null
      )
    );

    console.log(items)

Expected Output:

[
    {
       ...
       motorcycles: 'motorcycle01',
       cars: 'cars01'
    },
    {
       ...
       motorcycles: 'motorcycle01',
       cars: 'cars01'
    }
]

Answer №1

To expedite the process, consider creating a Map using the data01 data, with userId as the key.

Utilize Object.assign to transfer properties from a match. This method does not create a property if it is absent in the source data, ensuring there are no unnecessary null assignments (unless specified explicitly in the source):

let map = new Map(data01.map(o => [o.userId, o]));
items.forEach(a => Object.assign(a, map.get(a.userId)));

If you only require specific properties, generate objects containing only those particular properties:

let map = new Map(data01.map(o => 
    [o.userId, { cars: o.cars, motorcycles: o.motorcycles }]
));
items.forEach(a => Object.assign(a, map.get(a.userId)));

This alternate approach will always produce the designated properties, even if they did not previously exist. In such instances, their values will be listed as undefined.

Answer №2

To efficiently consolidate multiple arrays of objects based on a specific property within the objects, creating an intermediate map with userIDs as keys could be the most effective approach. This way, you can develop a method to update the map non-destructively while iterating through the arrays.

const data01 = [
      { userId: 0, motocycles: 'motocycle01', cars: 'car01' },
      { userId: 1, motocycles: 'motocycle02', cars: 'car02' },
      { userId: 2, cars: 'car03' },
      { userId: 3, motocycles: 'motocycle04' },
    ]

const data02 = [
      { userId: 0, dogs: 'doggy', cats: 'car01' },
      { userId: 1, dogs: 'doggo', cats: 'car02' },
      { userId: 2, dogs: 'sheperd' },
      { userId: 3, cats: 'kitty' },
    ]


function combineArrFromUserId(arr1,arr2){
  const idMap= new Map()
  data01.forEach(item=>checkAndAdd(item,idMap))
  data02.forEach(item=>checkAndAdd(item,idMap))
  return idMap.values()
}

function checkAndAdd(item,map){
  const current =  map.get(item.userId)
  if(current){
    map.set(item.userId,Object.assign(current,item))
  } else {
    map.set(item.userId, item)
  }
}

console.log(combineArrFromUserId(data01,data02))

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

Adjusting the THREE.js function to accommodate a new starting rotation angle

I am currently in the process of converting the code from into an AFRAME component. Everything works fine when the initial rotation is '0 0 0', but I am now attempting to set a different initial rotation. Thanks to @Piotr, who created a fiddle ...

Struggling with inserting JavaScript into the <input type="date"> calendar

Objective: I am trying to automate a calendar on Chrome using Selenium (Python + behave). The problem: Despite attempting to pass a value via JavaScript, the date is only set when physically clicked through the calendar. Keyboard input and JS method do no ...

Utilize ethereumjs-wallet in your web browser as a standalone module

I am looking to generate a wallet (which includes creating an account address and private key) directly in the browser without the need to connect to a node. It seems that in order to utilize web3.js, a provider (such as Metamask or localnode) needs to be ...

AngularJs Directive continuously returns undefined

Exploring angularjs directives for the first time has been quite a challenge. I can't seem to figure out why my directive isn't working properly as the scope.durationTimeInput always returns undefined no matter what I try. (function () { 'u ...

What is the most effective way to transfer JSON data to PHP?

I'm trying to retrieve the data for 'name', 'avl_bikes', and 'coordinates' from this website into my PHP. Below is my current code: <?php @ini_set("display_errors", 1); @ini_set("error_reporting", E_ALL); $string = f ...

Retrieve a specific item from a JSON response using Node.js

When I receive a message from a WebSocket, the code snippet is triggered like this: ws.onmessage = (e) => { debugger if (e.data.startsWith('MESSAGE')) alert(JSON.stringify(e.data)) ImageReceived(e.data) c ...

What steps can be taken to troubleshoot the 'unimplemented or irrational conversion requested' error?

I am facing an issue with passing a substantial amount of records as a stringify object from the client to the server. On the server side, there is a function named 'Get_Records' that is supposed to receive and process this string object by parsi ...

Issue with displaying Youtube search API results on EJS template file

I'm currently trying to integrate the YouTube Search API into my website. However, when I make the API call from my route, the results are returned but the page is rendered before the results finish processing - likely due to the asynchronous behavior ...

Can you suggest a way to revise this in order to include the type of property (string)?

Here is a snippet of working code that raises a question about refactoring to improve the readability and functionality. Consider renaming the method to isPropValueSame. import * as _ from 'lodash'; const diff = _.differenceWith(sourceList, comp ...

Split and show various JSON values in distinct <span> elements using ReactJS

Within my blogData JSON object, the key tags can contain multiple tag values. I want to display these tags separately inside span tags by iterating through them using the map function. Currently, all the tags are being displayed in a single span tag (show ...

Create a URL hyperlink using javascript

I am looking to create a link to a page that updates its URL daily. The main URL is where X represents the day of the month. For example, for today, July 20th, the link should read: In my JavaScript section, I currently have code that retrieves the cur ...

Make sure to validate onsubmit and submit the form using ajax - it's crucial

Seeking assistance for validating a form and sending it with AJAX. Validation without the use of ''onsubmit="return validateForm(this);"'' is not functioning properly. However, when the form is correct, it still sends the form (page r ...

Using deconstruction in exporting as default

As I was diving into a new codebase, I stumbled upon this interesting setup: //index.js export { default } from './Tabs' export { default as Tab } from './Tab' //Tab.js export default class Tab extends Component { render() => &ap ...

Updating values dynamically using AJAX within a v-for loop

I'm struggling to figure out how to change the value of an attribute in a v-for loop. For instance, I would like the index to be used as the name of the related product: HTML <div v-for="(index, publication) in publications"> {{ index | nam ...

Tips for configuring a file using javascript and angular.js

I am in need of some assistance. I would like to create a configuration file that stores all the paths for JavaScript files, which can then be dynamically called and included in the index page using Angular.js or JavaScript. The structure of my files is ex ...

Error encountered when deserializing Json Response into a Dictionary<string, object>: An unexpected end was reached while attempting to parse the object

Greetings! I am currently facing an issue with deserializing a JSON response that contains multiple blocks. The structure of the response is as follows: { [ { "WebCash" : { "Id" : 1021, "Rede ...

Using Ajax (Jquery) to send data to a PHP script

Currently, I am working on an application where users can click a checkmark to complete a task. When this action is taken, a popup window appears (created using bootstrap), prompting the user to enter their hours worked on the task. After entering the hour ...

Is there a more streamlined approach to coding in PHP and jQuery?

My PHP script: <?php $data = file_get_contents('http://newsrss.bbc.co.uk/rss/sportonline_uk_edition/football/rss.xml'); $xml = simplexml_load_string($data); $data1 = file_get_contents('http://www.skysports.com/rss/0,20514,11661,00.xml ...

Can I obtain a link through the branch_match_id parameter?

Within my application, there exists a hyperlink: hxxp://get.livesoccer.io/IuKk/0CRq5vArLx which leads to the following destination: hxxp://livesoccer.io/news.html?url=http%3A%2F%2Fwww.90min.com%2Fembed%2Fposts%2F4003374-chelsea-star-pedro-loving-life-at-s ...

disable caching for xmlhttp request

One issue I am facing is with a JavaScript function that retrieves JSON data via an Ajax request. The problem I'm encountering is that the browser starts caching the response to this request, which means I am not getting the most recent data from the ...