A method to verify both properties are identical in all items within an array of objects

I have an array of objects that I need to manipulate by combining entries with the same key/values for 'name' and 'size'. Here is the original array:

[
  {
    id: 1,
    name: "foo",
    size: 4998,
    relatedId: 17,
    link: "https://www.google.com/"
  },
  {
    id: 2,
    name: "foo",
    size: 4998,
    relatedId: 21,
    link: "https://www.google2.com/"
  },
  {
    id: 3,
    name: "bar",
    size: 381,
    relatedId: 35,
    link: "https://www.google3.com/"
  },
  {
    id: 4,
    name: "bar",
    size: 381,
    relatedId: 41,
    link: "https://www.google4.com/"
  },
  {
    id: 5,
    name: "baz",
    size: 666,
    relatedId: 50,
    link: "https://www.google5.com/"
  },
]

The desired output should look like this:

[
  {
    id: 1,
    name: "foo",
    size: 4998,
    relatedId: 17,
    link: "https://www.google.com/",
    relations: [
      {
        id: 1,
        relatedId: 17
      },
      {
        id: 2,
        relatedId: 21
      }
    ]
  },
  {
    id: 3,
    name: "bar",
    size: 381,
    relatedId: 35,
    relations: [
      {
        id: 3,
        relatedId: 35
      },
      {
        id: 4,
        relatedId: 41
      }
    ]
  },
  {
    id: 5,
    name: "baz",
    size: 666,
    relatedId: 50,
    relations: [
      {
        id: 5,
        relatedId: 50
      }
    ]
  }
]

To achieve this, a new property called relations needs to be added to the objects. If multiple objects share the same name and size, all but the first entry should be removed and their id and relatedId pushed to the relations array.

Here is the attempted function that has not worked as expected yet:

mergeDuplicates (fileArray) {
    for (let i = 0; i < fileArray.length; i++) {
        fileArray[i].relations = []
        fileArray[i].relations.push({
            id: fileArray[i].id,
            relatedId: fileArray[i].relatedId,
        })
        for (let j = 1; j < fileArray.length; j++) {
            if (fileArray[i].name === fileArray[j].name && fileArray[i].size === fileArray[j].size) {
                fileArray[i].relations.push({
                    id: fileArray[j].id,
                    relatedId: fileArray[j].relatedId,
                })
                fileArray.splice(j, 1)
            }
        }
    }

    return fileArray;
}

Answer №1

One way to create a map of values, organized by name and size, is to utilize the Array.reduce method.

To finalize the result, we can then make use of Object.values:

const input = [ { id: 1, name: "foo", size: 4998, relatedId: 17, link: "https://www.google.com/" }, { id: 2, name: "foo", size: 4998, relatedId: 21, link: "https://www.google2.com/" }, { id: 3, name: "bar", size: 381, relatedId: 35, link: "https://www.google3.com/" }, { id: 4, name: "bar", size: 381, relatedId: 41, link: "https://www.google4.com/" }, { id: 5, name: "baz", size: 666, relatedId: 50, link: "https://www.google5.com/" }, ] 

const result = Object.values(input.reduce((acc, cur) => {
    // Key our map using name and size 
    const key = cur.name + cur.size;
    // If nothing exists at the key, create a new one...
    acc[key] = acc[key] || { ...cur, relations: []};
    acc[key].relations.push({ id: cur.id, relatedId: cur.relatedId });
    return acc;
}, {}))

console.log("Result:",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

The function vm.handleClick does not exist in Vue.js

I have been trying to implement toggle buttons from the argon template and came across an issue. Here is the code snippet: <template> <div class="option"> <div>Show value <label class="custom-toggle"> &l ...

JavaScript tip: Improve the way you highlight the current navigation page while scrolling by finding alternative methods to using "scrollY > x"

Currently, my webpage layout is divided into 4 sections - HOME, ABOUT, SKILLS, and CONTACT. Below is the JavaScript code I am using to highlight a specific section on the navigation bar based on the scroll position: let home = document.querySelector(" ...

Is it possible to blur the element and its parent element before the element's blur handler executes?

Here is the HTML code snippet: <div id="SomeDiv"> <input id="SomeInput" /> <div id="ChildDiv"></div> </div> An event handler is set to trigger on the blur event for SomeInput. This handler checks if either SomeDiv or a ...

Using Vue JS to handle image upload with "PROP MUTATING"

Apologies for any language barriers or inaccuracies in my English. I have a single component designed specifically for image uploads. It is currently being utilized in two forms: an add form and an edit form. In the edit modal, the Image URL is passed as ...

webpack - compile one TypeScript file separately (2 actions)

In summary... When my Vue files are combined with background.ts, webpack processes them to create bundled vue files along with background.js I'm unable to run the background.js script I expected background.js to only contain "console.log(' ...

Trouble with escape sequences in regular expressions within jQuery Terminal for JavaScript

I'm experimenting with special character functionality in jQuery terminal. While I was successful in implementing the backspace functionality, I encountered an issue when trying to execute the escape functionality. Below is the code snippet I used: ...

Having trouble getting an Angular directive to bind a click event to an external element?

I've been working on creating a unique custom event for toggling with Angular. The directive I'm using is called toggleable. It may sound simple at first, but the tricky part is that I want to be able to use any button or link on the page for to ...

Utilizing useState to validate the selection of all radio buttons

Within my React Application, I am integrating a series of questions fetched from the backend and presented to the user for selection using radio buttons: <RadioGroup row> {data.response.map((dt, rIndex) => { r ...

Updating a field in Mongoose by referencing an item from another field that is an array

I have developed an innovative Expense Tracker Application, where users can conveniently manage their expenses through a User Collection containing fields such as Name, Amount, Expenses Array, Incomes Array, and more. The application's database is p ...

Add drop caps to every individual word within a hyperlink

Is there a way to recreate the menu effect similar to using CSS fonts and drop caps for each word? I'm aware of the CSS code: p.introduction:first-letter { font-size : 300%; } that enlarges the first character of the first word, but I want this ef ...

Are Twitter Bootstrap buttons compatible with iPad devices?

Have you ever tried using the attractive buttons provided by Twitter? They can be a great alternative to standard radio/checkbox options. If you have used them in your production, how effective were they? I am particularly curious about their compatibilit ...

Issues with sending empty strings to an API in Vue Js

My code below is designed to update data using a Node Js REST API. The remaining field contains an equation using v-model=remaininginst to calculate and store the result in remaininginst. However, when I check the console.log, I am getting NaN empty data s ...

JQuery is blocking the submission of an HTML form

During my exploration of an AJAX/JQuery tutorial for a registration script that interacts with PHP/MySQL and is submitted via JQuery, I encountered a recurring issue. The problem lies in the form submitting directly to the action page instead of its intend ...

Update MYSQL table values using AJAX and jQuery, then dynamically refresh the updated values on the web page

Hey there! I am fairly new to utilizing ajax and encountering some difficulty with a fundamental concept. In my MySQL table called "users," I have various user information stored, including the balance they pledge to donate. My goal is to create a div elem ...

Add items to a separate array only if the material UI checkbox is selected

Exploring the world of React, I decided to create a simple todo app using React JS and Material UI. With separate components for user input (TodoInput.js) and rendering individual todos with checkboxes (TodoCards.js), I aim to display the total number of c ...

Transform a single data point into pixels by converting its latitude and longitude coordinates

I am facing a specific challenge where I have hit a roadblock after conducting some research. The issue at hand is this: I am working with a raster image that has known dimensions (800 x 800 px) I have two points within this image with their pixel and g ...

Trouble encountered with card flip style login form in Vue.js, as the card is not maintaining its position properly during transition animations

Need help styling a login/signup component in Vue.js where flipping between the two cards isn't working smoothly. The transition is causing one card to move down and right while the other comes in from the bottom right. It's hard to explain the i ...

Is it possible to include a JavaScript file in another JavaScript file synchronously?

Is there a way to import external JavaScript files into my HTML file without causing any issues? Similar to how @import works in CSS. I've seen suggestions like appending a script tag to the DOM on websites like StackOverflow, but this method loads t ...

Performing multilevel verification through Puppeteer's `waitForFunction`

Utilizing the Puppeteer page.waitForFunction() method: await page.waitForFunction(` (window.hero.x - 1 === ${x} || window.hero.x === ${x} || window.hero.x + 1 === ${x} || window.hero.x === ${x}) && (window.hero.y - 1 === ${y} || window.hero.y = ...

Storing an object in a model using MongoDB and Express

I have created a user schema in mongoose with various fields such as userName, firstName, lastName, password, rate, and rates. I am trying to perform a PUT request to store a new key/value pair in the rates object. Before updating the rates, I check if ...