Contrast and combine information from two JavaScript arrays of objects

I am struggling with comparing two arrays of objects based on a key.

My goal is to compare the values, subtracting them when the keys match and displaying negative values for those not found in my target array. Additionally, I want to include all target objects that do not have matching keys in my final array.

An example can illustrate this scenario better:

const initial = [{id: 1, value: 47}, {id: 2, value: 20}, {id: 7, value: 13}];
const target = [{id: 1, value: 150}, {id: 3, value: 70}, {id: 40, value: 477}];

// Desired output
// [{id: 1, value: 103}, {id: 2, value: -20}, {id: 7, value: -13}, {id: 3, value: 70}, {id: 40, value: 477}];

let comparator = [];

initial.map(initia => {
   let hasSame = target.find(targ => {
        return initia.id === targ.id;
      });
            
     if(hasSame) {
        initia.value -= hasSame.value;
     } else{
        initia.value = -initia.value;
    }
});

console.log(initial);

I have almost achieved the desired result, but I am unsure how to properly merge the target values. Is there a way to accomplish this without iterating through the target array again? Can it be done within the find method?

I would appreciate any advice or guidance on achieving this task efficiently.

Thank you!

Answer №1

A method to achieve the desired outcome is by utilizing a Map, where you can gather similar id values along with a specified factor for adding them up.

The next step involves assigning key/value pairs as new attributes.

var add = (map, factor) => ({ id, value }) => map.set(id, map.has(id)
        ? map.get(id) - value * factor
        : value * factor
    ),
    initial = [ {id: 1, value: 47 }, { id: 2, value: 20 }, { id: 7, value: 13 }],
    target = [{ id: 1, value: 150 }, { id: 3, value: 70 }, { id: 40, value: 477 }],
    map = new Map,
    result;
    
initial.forEach(add(map, -1));
target.forEach(add(map, 1));
result = Array.from(map, ([id, value]) => ({ id, value }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

In order to avoid nesting a find operation inside a loop, another approach could be used by combining the two arrays into a Set. Sets do not allow duplicate keys, ensuring only one value for each provided ID.

const valueSet = [...initial, ...target].reduce((total, obj) => {
  total[obj.id] = !total[obj.id] 
    ? -obj.value
    : total[obj.id] -= obj.value
  return total;
}, {});

const result = Object.keys(valueSet).map(key => ({ id: key, value: valueSet[key]}))
console.log(result);

Subsequently, the result can be mapped back over to construct the desired array structure.

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

Attempting to create a dynamic dropdown menu with animated effects triggered by a key press

I've been attempting to construct a menu that initially appears as a small icon in the corner. Upon pressing a key (currently set to click), the checkbox is activated, initiating the animation. Most of the menu and animation are functional at this po ...

What steps can be taken to resolve the issue of the <td> element not being allowed as a child of an <a> tag?

https://i.stack.imgur.com/nsdA7.png How can I address these warnings? I utilized the material UI table component and suspect that the warnings are originating from component={Link} to={/patient/${patient.id}} <TableContainer className={styles.tableCo ...

Avoiding multiple ajax requests due to multiple clicks

I have a blog on WordPress that has a jQuery code allowing users to click a bookmark link to save the post as a bookmark. Each post displays a total bookmark counter in this format: "Bookmarked (5)". The issue is that when a user clicks multiple times on t ...

Pattern matching to verify a basic number within the range of [0-6]

const number = '731231'; const myRegex = /[0-6]/; console.log(myRegex.test(number)); Could someone provide some insight into this code snippet? In my opinion, the regular expression [0-6] should only match numbers between 0 and 6. However, i ...

Tips for effectively utilizing the Ngrx navigation function

While exploring NgRx, I stumbled upon navigation. According to the documentation, it seems like this effect should trigger when the component loads. However, I'm facing an issue where this effect is not getting triggered. Other effects that I've ...

Efficiently converting HTML object data into plain text using RegExr in ReactJS and JavaScript

Is there a way to convert an object in JavaScript/ReactJS into a string? For instance, consider the following object: { article: '<p class="md-block-unstyled">First text...</p><p>Second text></p>' } I am looking to ...

Run a targeted command on AWS Beanstalk

I have a unique node.js application that specifically functions with sqlite. I am interested in conducting a 'proof of concept' on AWS ElasticBeanstalk without the need to adjust the node.js app to be compatible with a supported database Prior ...

Discovering the RGB color of a pixel while hovering the mouse in MapboxGL Js

Looking to retrieve the RGB color value of the pixel under the mouse hover in MapboxGL Js. What is the most effective method to accomplish this task? ...

Transferring user inputs to the server through jQuery-AJAX

I've encountered some issues when trying to send form data inputs to the server. Despite alerting each form input, I keep getting empty alerts. Here's my code snippet: With my current code, it only alerts 0. However, posting normally seems to wor ...

How odd! Using window.location or location.replace redirects to the page and then reverses back!

While in debug mode, I am able to track which page is being accessed. Interestingly, whenever I use window.location or window.location.replace(..), the browser redirects to the specified page but then quickly returns to the original one! This strange beh ...

Issue with Bootstrap Carousel: all elements displayed at once

I'm in the process of building a carousel. I have set up the structure, but I only want five blocks to be visible initially, with the sixth block appearing after clicking an arrow. How can I achieve this? My strategy: (adopted from here) img{ b ...

Creating a pattern for values ranging from 18 to 99, including leading zeros, using regular expressions

Looking for a Regular Expression that matches numbers from 018 to 099, inclusive. The numbers must range between 18 and 99, and include a leading zero for values less than 100. ...

Troubleshooting: My jQuery script for fading in content upon document ready is not

I'm currently working on a website where I want everything to fade in when the user enters the site. Take a look at my code: var celyLogin = $(".container"); $(document).ready(function () { /*! Fades in page on load */ $("container") ...

Tips for ensuring that the toJSON method in Sails.js waits for the find operation to complete before returning the object

When I try to run a find inside the toJSON function in the model, the object is returned before the find completes. How can I ensure that the return happens only after the find operation has completed? toJSON: function() { var obj = this.toObject(); Com ...

The art of posting with ExpressJS

I'm encountering a problem where the data submitted through a form to my POST route is not getting passed on to a database document, even though the redirection works fine. I'm unsure of how to troubleshoot this issue. blogpost-create.ejs &l ...

Ways to modify input value based on another input in VueJS

Two sets of text boxes are displayed in a grid format, which can be viewed here. The objective is for users to fill out the top boxes and have the values automatically update as they fill out the corresponding bottom boxes. For example, if you input 100 i ...

Using AngularJS to hide elements within a nested dictionary structure

My dictionary structure is as follows: var data = { a: [1, 2, 3, 4, 5], b: [ [1, 2], [3, 4], [5, 6] ] }; Currently, I am using ng-hide to hide an element if the value 2 exists in data->a. Here's how it's implemented: <i ...

Why is the React onClick method returning undefined upon the first selection, and why are the values being passed not consistent with

While attempting to create a list of users that, when clicked, should open up a corresponding user's message, I encountered an issue where clicking for the first time resulted in an 'undefined' value being passed. I've tried troublesho ...

loading preloaded fonts at the optimal moment

My webfonts are loaded using Webfontloader as shown below: <script src="//ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script> <script> WebFont.load({ custom: { families: ['BlenderProBook' ...

What is preventing the selected values of a dropdown element from being set?

Although it may seem simple to assign values to select elements, I'm puzzled as to why the code below is setting the values to null instead of the correct ones for "form-type" and "genre". All other fields are being set correctly. It's worth not ...