Merge two arrays of objects in Ramda.js based on their shared ID property

I'm working with two arrays of objects:

todos: [
    {
      id: 1,
      name: 'customerReport',
      label: 'Report sent to customer'
    },
    {
      id: 2,
      name: 'handover',
      label: 'Handover (in CRM)'
    },
  ]

And:

todosMoreDetails: [
          {
            id: 1,
            checked: false,
            link: {
              type: 'url',
              content: 'http://something.com'
            },
            notes: []
          },
          {
            id: 2,
            checked: false,
            link: {
              type: 'url',
              content: 'http://something.com'
            },
            notes: []
          }
        ]

My goal is to merge the two arrays based on the object ID, resulting in a final array like this:

FinalTodos: [
          {
            id: 1,
            checked: false,
            link: {
              type: 'url',
              content: 'http://something.com'
            },
            notes: [],
            name: 'customerReport',
            label: 'Report sent to customer'
          },
          {
            id: 2,
            checked: false,
            link: {
              type: 'url',
              content: 'http://something.com'
            },
            notes: [],
            name: 'handover',
            label: 'Handover (in CRM)'
          }
        ]

I've been attempting to achieve this using methods like merge, mergeAll, and mergeWithKey, but it seems like I'm missing something.

Answer №1

To accomplish this task, utilize an intermediate groupBy approach:

Convert the todosMoreDetails array into an object categorized by the todo property ID using groupBy:

var moreDetailsById = R.groupBy(R.prop('id'), todosMoreDetails);

The moreDetailsById object contains keys representing IDs and values as arrays of todos. If the ID is unique, it will be a singleton array as follows:

{
      1: [{
        id: 1,
        checked: false,
        link: {
          type: 'url',
          content: 'http://something.com'
        },
        notes: []
      }]
}

Now merge each todo with its corresponding details fetched from the grouped view in the todos array:

var finalTodos = R.map(todo => R.merge(todo, moreDetailsById[todo.id][0]), todos);

An alternative, more detailed method:

function mergeTodo(todo) {
   var details = moreDetailsById[todo.id][0]; // this is not null safe
   var finalTodo = R.merge(todo, details);
   return finalTodo;
}

var moreDetailsById = R.groupBy(R.prop('id'), todosMoreDetails);
var finalTodos = todos.map(mergeTodo);

Answer №2

It seems like the merge function is primarily used for arrays. Consider looking into the "extend" object method as an alternative. Perhaps consolidating the todo details into a single object could be a more efficient solution.

Example using underscore:

var result = [];
var entry = {};
_.each(todos, function(todo) {
    _.each(todosMoreDetails, function(detail) {
        if (todo.id == detail.id) {
            entry = _.extend(todo, detail);
            result.push(entry);
        }
    }
});
return result;

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

Unraveling nested JSON structures with varying formats in Javascript or Jquery: Step-by-step guide

var cart = [ { "Items": "", "category": "", "contents": [ { "Apple iPhone": "222", "French": "Bounjour", "id": 1234, "icon": "/images/bg.jpg", "callback": "use()", "pricetag":"false" } ] }, { "Items": "No 2" ...

Utilizing the power of THREE.ShaderLib.phong while integrating subsurface scattering within ThreeJS

My mesh utilizes a ShaderMaterial with THREE.ShaderLib.phong uniforms. I have successfully linked the map, bump, and specular maps textures. The code snippet below demonstrates this: defines = {}; defines["USE_MAP"] = ""; defines["USE_BUMPMAP"] = ""; defi ...

`Is it possible to remove an empty frame using javascript?`

I have this script that generates a "layer" resembling a frame and I need to remove it. Here is the code for creating the layer: function disableLayer() { var layer = document.getElementsByTagName('div')[0]; d = document.createElement(& ...

What is the best way to display my 'React Loading Spinner' component at the center of my view?

Whenever I use the Loading as my parent component for the Layout component, it always shows up in the center of the page instead of within my view. How can I adjust its positioning? ...

Is there a way to check if a file name input is valid using regular expressions?

I'm having trouble getting my code below to work properly. I'm not sure if the problem lies in the match function syntax or the regex itself. Any assistance would be greatly appreciated. $scope.fileSelected = function (file) { var valid = "/ ...

What is the process of defining a route for a JSON response in an Express application?

I've been following an Angular tutorial on handling form submissions with promises, which I found here. My server is running on Node and I'm using Express to manage routes. However, when I submit the form and reach the line var $promise = $http. ...

Personalized information boxes for particular data points within highcharts

When hovering over specific points, I want to display unique warnings or explanations in the tooltip. I have included custom text like 'WARNING' and 'WARNING 2' within the series data but am struggling to retrieve that data for each too ...

Is it best practice to use the AngularFirestoreCollection for updating Firestore items in AngularFire?

Within my application, I have a list that necessitates the use of an "or" condition. However, according to the documentation: "In this case, you should create a separate query for each OR condition and merge the query results in your app." Consequently ...

Update in slide height to make slider responsive

My project involves a list with text and images for each item: <div class="slider"> <ul> <li> <div class="txt"><p>First slogan</p></div> <div class="img"><img src="http://placehold.it/80 ...

Creating two interactive animations utilizing a combination of CSS and Javascript, triggered by the click event on

Looking to incorporate two unique CSS animations into my project. Utilizing two buttons and one object, I want the first animation to trigger upon clicking the first button. I understand how to handle one button and one animation, but am unsure how to man ...

issue with manipulating URLs in Express routing

Looking for assistance with Express routing. I want users to only see localhost:3000/page2 when they go to /page2, instead of localhost:3000/page2.html I have three HTML pages - page1.html, page2.html, and page3.html. I've created a server using Expr ...

The try and catch block in JavaScript is failing to correctly capture the HTTP status

I have a function that successfully posts JSON to an API endpoint. Here is the code I am using: function sendValuesPageLoad(){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { try { if (xhr.readyState === ...

Vue alert: Issue encountered in data() - "TypeError: Unable to convert undefined or null to object"

Can anyone help me figure out how to remove this warning? I suspect it's because I'm trying to manipulate an undefined object. Any assistance would be greatly appreciated! Thank you! Here is the code snippet: <v-card class="ma-3 pa-3" v-for=" ...

Send the user to the login page once their email has been verified

On my website, I have a process where users need to verify their email by clicking on a link sent through emails. When the user clicks on this verification link, I want them to be redirected to a page thanking them for confirming their account and then a ...

The placeholder feature seems to be malfunctioning when it comes to entering phone numbers in a react

I am working on a MUI phone number form field. I want the placeholder to show up initially, but disappear when the user starts typing. How can I achieve this functionality in my code? import React from "react"; import MuiPhoneNumber from " ...

What is the best way to have a variable adjust each time a coin is inserted until it reaches a specific value?

I have developed a unique coin box that recognizes the value of each coin inserted. Users can now pay for a service that costs 2.0 € by inserting coins of various denominations such as 2.0 €, 1.0 €, 0.50 €, 0.20 €, and 0.10 €. In my react-nati ...

Issues encountered when executing unit tests using karma

I encountered these issues in the logs. Seeking advice on how to proceed. Thank you. I've attempted uninstalling and reinstalling phantomjs, clearing out my node modules and bower component directories. Everything was functioning as expected before, a ...

Guide to appending the chosen item from a search bar to a fresh array using vue3 js

Does anyone know how to resolve the issue I'm facing with adding selected items from a dropdown list to a new array and displaying them on the page? Currently, I have added an onblur event to the input field to hide the dropdown when clicked outside, ...

The server is unable to process your request to /graphql

I've encountered an issue while setting up the GraphiQL API. I keep receiving the error message "Cannot POST /graphql" on both the screen and network tab of the console. Despite having similar boilerplate code functioning in another project, I'm ...

Exploring ES6 Property Assignment

After researching, I've discovered that ES6 does not support setting properties of a class and returning that class. class MyClass { constructor() { this.x = 0; this.y = 0; } update(value) { // logic this.y ...