What is the best way to merge arrays within two objects and combine them together?

I am facing an issue where I have multiple objects with the same properties and want to merge them based on a common key-value pair at the first level. Although I know about using the spread operator like this:

const obj3 = {...obj1, ...obj2}

The problem arises when there are arrays inside the objects that end up getting overwritten instead of being merged seamlessly.


{
  "id": 1,
  "name": "firstLevel",
  "visible": true,
  "subCategories": [
    {
      "id": 2,
      "name": "secondLevel",
      "visible": true,
      "skills": [
        {
          "name": "foo",
          "id": 5,
          "visible": true
        }
      ]
    }
  ]
}

{
  "id": 1,
  "name": "firstLevel",
  "visible": true,
  "subCategories": [
    {
      "id": 2,
      "name": "secondLevel",
      "visible": true,
      "skills": [
        {
          "name": "bar",
          "id": 1,
          "visible": true
        }
      ]
    }
  ]
}

My desired outcome is for the objects to combine in such a way that the arrays within them get merged, resulting in:


{
  "id": 1,
  "name": "firstLevel",
  "visible": true,
  "subCategories": [
    {
      "id": 2,
      "name": "secondLevel",
      "visible": true,
      "skills": [
        {
          "name": "foo",
          "id": 5,
          "visible": true
        },
        {
          "name": "bar",
          "id": 1,
          "visible": true
        }
      ]
    }
  ]
}

Answer №1

If you need to combine arrays and plain object properties in a recursive manner, you should consider using lodash.mergeWith.

var object = {
  'a': [{ 'b': 2 }, { 'd': 4 }]
};
 
var other = {
  'a': [{ 'c': 3 }, { 'e': 5 }]
};

function customizer(objValue, srcValue) {
  if (_.isArray(objValue)) {
    return objValue.concat(srcValue);
  }
}
 
_.mergeWith(object, other, customizer);
// => { 'a': [{ 'b': 2 }, { 'c': 3 }, { 'd': 4 }, { 'e': 5 }] }

If you have specific object ids that you know beforehand, this customizer function can be utilized as needed.

function customizer(objValue, srcValue) {
  if (_.isArray(objValue)) {
    for (const srcItem of srcValue) {
      const objItem = objValue.filter(item => item.id === srcItem.id);
      if (objItem.length) {
        objValue = objValue.map(item => {
          if (item.id === objItem[0].id) {
            return _.mergeWith(item, srcItem, customizer);
          }

          return item;
        });
      } else {
        objValue = [...objValue, srcItem];
      }
    }

    return objValue;
  }
}

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

What is the best way to generate script code dynamically on an HTML page depending on the environment?

I am facing a challenge with my asp.net application. I need to insert a dynamic script into the html section, and this script's value must change depending on the environment (TEST, QA, etc.). To illustrate, here is the script where DisplayValue is th ...

Navigating programmatically to another page in Next.js can be easily achieved by utilizing the useRouter hook

Following a post request to an external API, my goal is to navigate back to the homepage. While I am familiar with React, this is my first experience using Next.js. Here's the snippet of code: export default function New({genres}) { const createMovie ...

Prevent form submission with jQuery during validation process

Currently, I am working on validating a form using jQuery. My main objective now is to have the submit button disabled until all fields are correctly filled in. To achieve this, I have implemented the following approach: http://jsfiddle.net/w57hq430/ < ...

React - assigning a value to an input using JavaScript does not fire the 'onChange' event

In my React application with version 15.4.2, I am facing an issue where updating the value of a text input field using JavaScript does not trigger the associated onChange event listener. Despite the content being correctly updated, the handler is not being ...

Having difficulty accessing `props` in a React JS and Next JS application

Currently, I am developing a React application that utilizes Server Side Rendering. In this project, I am using React Js and Next Js as my primary framework. My goal is to retrieve initial props using the getServerSideProps method by consulting the documen ...

Having trouble with firebase admin code completions not functioning properly in vscode?

I've attempted to install the Typescript integration for Firebase using: npm install --save-dev @types/firebase Unfortunately, I have not had any success. The "firebase-admin" and "firebase-functions" packages do not provide code completion or intel ...

Instead of using a string in the createTextNode() function, consider utilizing a variable

I am attempting to use JavaScript to add another list item to an unordered list. I want the list item to display dynamic content based on a pre-existing variable. While I can successfully append a list item by using a string, things go awry when I try to i ...

What separates the functions `useRef` and `createRef` from each other?

As I was delving into the hooks documentation, I came across useRef. Upon examining their example… function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { // `current` refers to the mounted text inpu ...

The dot notation in JSON syntax allows for easy access

Recently, I've been struggling with referencing a variable in JSON dot notation within my meteor application. It seems that when trying to access respJson.userlower.name, userlower is not being recognized as a valid variable. Is there a workaround for ...

Failed commitments in Protractor/WebDriverJS

WebdriverIO and Protractor are built on the concept of promises: Both WebdriverIO (and as a result, Protractor) APIs operate asynchronously. All functions return promises. WebdriverIO maintains a queue of pending promises known as the control flow to ...

Loop over elements retrieved from Firebase using ng-repeat

I am currently attempting to iterate through items retrieved from Firebase using ngrepeat. Although I can see the items in the console, the expressions are not working as expected. I have tried various solutions, but nothing seems to be working. Any assist ...

"Combining AngularJS with Material Design disrupts the functionality of infinite scroll

Issue: Infinite scroll is loading all pages at once instead of waiting for the user to scroll to the page bottom. Environment: AngularJS 1.3.17 Materials Design 0.10.0 Infinite scroll script: https://github.com/sroze/ngInfiniteScroll Demo being used: The ...

Activating a link without clicking will not trigger any javascript functions

I have been attempting to display an image when I hover over a link, but for some reason, the .hover() event is not functioning as expected. Initially, I am just aiming to have an alert pop up. Once I have that working, I can proceed with fading elements i ...

Make sure to always select the alternative option in ajax

I am trying to create a condition where if the value of id=type_investor is either 1 or 6, an email should be sent using a different controller. Here is my complete code: function (isConfirm) { if (!isConfirm) return; $.ajax({ ...

Trigger the jQuery function once the external URL loaded via AJAX is fully loaded

Currently, I am in the process of developing a hybrid mobile app for Android and I am relatively new to this technology. I have two functions in jQuery, A and B. Function A is responsible for making an AJAX request to retrieve data from 4 external PHP fi ...

What is the procedure for turning off hover color on an href element?

Working on a website that utilizes MUI components, I have incorporated href into the Tab elements within the navigation bar. <Tab label={element} id={index} sx={{display: {xs: 'none', md: 'inherit'}}} href={`#${navElements[element ...

What is the best method for clearing all session cookies in my React application?

Currently, I am working on a project using React. I am trying to find a method to automatically logout the user by deleting all of the session cookies in my React application. However, I have not been able to come up with a solution yet. Is there a way to ...

Using RxJs in Angular, you can invoke an observable from within an error callback

I have a scenario where two observable calls are dependent on each other. Everything works fine, but when an error occurs in the response, I need to trigger another observable to rollback the transaction. Below is my code: return this.myService.createOrde ...

Which is the optimal choice: subscribing from within a subscription or incorporating rxjs concat with tap?

After storing data in the backend, I proceed to retrieve all reserved data for that specific item. It is crucial that the data retrieval happens only after the reservation process to ensure its inclusion. Presented with two possible solutions, I am cont ...

Is there a way to automatically scroll the parent page's top when the user navigates within an iframe?

We are encountering an issue with the loading of the iFrame. When the iFrame loads on the client's page, we notice that the page location jumps around and, in most cases, the page focus is lower down the page. This requires users to scroll up to view ...