How to categorize an array of objects based on a specific property while preserving the original object attributes

I have an array of objects with a specific property that I want to group by. My objective is to create a new array where all the objects have the same properties, but with an additional property that combines all the "value" properties into an array.

Here is the input data along with the desired output. How can I achieve this?

INPUT

[  {
        group_by_this_property: 1,
        value: 100,
        class: 'A',
      },
      {
        group_by_this_property: 1,
        value: 101,
        class: 'A',
      },
      {
        group_by_this_property: 1,
        value: 102,
        class: 'A',
      },
      {
        group_by_this_property: 2,
        value: 200,
        class: 'B',
      },
      {
        group_by_this_property: 2,
        value: 201,
        class: 'B',
      }
    ]

OUTPUT

[
  {
    group_by_this_property: 1,
    values: [100, 101, 102],
    class: 'A',
  },
  {
    group_by_this_property: 2,
    values: [200, 201],
    class: 'B',
  },
]

Answer №1

To organize the items into groups, you can utilize a Map structure and retrieve the values at the end like this:

const data = [ { key_property: 1, value: 100, type: 'A' }, { key_property: 1, value: 101, type: 'A' }, { key_property: 1, value: 102, type: 'A' }, { key_property: 2, value: 200, type: 'B' }, { key_property: 2, value: 201, type: 'B' } ];

const result = [...
  data.reduce((map, { key_property, value, ...properties }) => {
    const { groupValues = [] } = map.get(key_property) ?? {};
    groupValues.push(value);
    map.set(key_property, { ...properties, key_property, groupValues});
    return map;
  }, new Map)
  .values()
];

console.log(result);

Answer №2

Let me provide you with a couple of illustrative scenarios. One employs the reduce function.

inputArr.reduce((acc, curr) => {
    const existingGroup = acc.find(item => item.group_by_this_property === curr.group_by_this_property);
    if (!existingGroup) {
        acc.push({
            ...curr,
            values: [curr.value]
        });
        delete curr.value;
        return acc;
    }

    existingGroup.values.push(curr.value);
    return acc;
}, [])

Additionally, here is another method utilizing a traditional for loop.

const hashMap = {};
const res = [];
for (let index = 0; index < foo.length; index++) {
    const element = inputArr[index];
    if(element.group_by_this_property in hashMap) {
        hashMap[element.group_by_this_property].values.push(element.value);
    } else {
        hashMap[element.group_by_this_property] = {
            ...element,
            values: [element.value]
        };
        delete hashMap[element.group_by_this_property].value;
        res.push(hashMap[element.group_by_this_property]);
    }
}

Why present two methods? Well, in terms of clarity, one could argue that the first approach is more straightforward and user-friendly. However, for larger datasets, it may become somewhat convoluted as it operates at O(n^2), impacting the performance of this algorithm.

The second approach accomplishes the same task in linear time complexity of O(n). If speed is not a critical factor for your needs or the dataset is relatively small, the first example would suffice.

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

Transmit Array of Preferred Values to Controller in MVC Framework

After setting up a view with a search box and buttons labeled "Add" (btn-default) and "Edit" (breadcrumb), I encountered an issue when attempting to pass selected values from the search box to another controller upon clicking the Edit button. Unfortunately ...

How can I ensure that the ons-scroller stays at the bottom when writing a JavaScript code in Onsen UI?

How can I ensure the ons-scroller stays at the bottom when writing JavaScript? This is the code I am using: <ons-page> <ons-toolbar> <div class="left"><ons-back-button>Return</ons-back-butto ...

Deploy a Node.js websocket application on Azure Cloud platform

After smoothly running on Heroku, the server app encountered a problem with startup after moving to Azure. Below is the code snippet: const PORT = process.env.PORT || 2498; const INDEX = '/index.html'; const server = express() .use((req, res ...

Why does Axios keep timing out despite successful testing in Postman?

Trying to set up a single request for my app using axios with express/node js. Here is the code snippet that was generated through the Postman app. I have attempted different variations by creating my own form, but I always end up with the same result. co ...

use dotenv in your Build Folder

Is it possible to have my .env file in my React JS project move to the build folder when I run NPM build command? If so, how can this be achieved? If not, what would be the alternative solution? I attempted using "build": "cp .env.template ...

Turn off and then turn on user input without exiting the textarea

I've been working on a small project that requires me to enable and disable text input in a textarea using key commands, similar to Vi/Vim's insertion and command modes. However, I'm struggling to find an elegant solution. Disabling the tex ...

Unable to execute commitlint in husky along with a different custom command

Is it possible to set up two precommit hooks with husky? Specifically, I want to integrate commitlint along with a custom script specified in my package.json. After installing husky and creating a pre-commit script in the .husky folder, here is what I have ...

Retrieve the modal ID when the anchor tag is clicked in order to open the modal using PHP

I am facing an issue with opening a modal and passing the id value using JavaScript. The id value is shown in a hidden input field. <a href="#modal2" data-toggle="modal" data-id="<?php echo $CRow['id'];?>" id="<?php echo $CRow[& ...

I am looking to integrate a custom button that, when clicked, will launch the file explorer for me to choose a file. Once selected, the file name should automatically populate in the input field

In the code below, when the button is clicked, Windows Explorer should open and allow the user to select a file. The selected file should then be displayed in the input field. The file type should not be 'File'. <Grid.Column width={8}> ...

transferring information between two html pages using javascript

Although this question has been raised multiple times, I have gone through the answers and attempted various solutions, however, my code is still not functioning correctly. Below are my working files : my_app -index.html -task1 -index.html I ...

Creating a JSON file in UTF-8 format using PHP code within a WordPress plugin

I'm currently developing a WordPress plugin that requires the capability to both write and read complex data encoded as JSON, potentially containing UTF-8 encoded text. I've encountered issues when attempting to read the file, as it results in PH ...

Exploring an array to retrieve a specific value

Can someone assist me? I am looking to create a JavaScript function that follows the structure of the code example below. Unfortunately, I do not have enough programming skills to develop a functional solution from scratch. The goal is to input a value, ...

How can I achieve the quickest image loading speed with JavaScript?

If I have a large ecommerce website with 15,000 image elements that need to be added to the HTML, what is the best approach using JavaScript to optimize efficiency and enhance user experience? ...

Having trouble positioning a div in AngularJS so that it stays pixel-perfect regardless of browser resize or device orientation? Unfortunately, it's

I am a newcomer to AngularJS and have been struggling with a particular issue for several days now, leading me to suspect that I may be using it incorrectly. The problem at hand involves positioning 30 divs in a specific manner: 1) Each div should displa ...

Utilize jQuery to choose a specific tab

I have implemented a jquery tab in my UI. I want to have the second tab selected when the page loads, instead of defaulting to the tab with the "Active" class. Here is my HTML tab code: <div class="typo"> <div class="container-fluid"> ...

The window.Print() function is currently experiencing a glitch in Microsoft Edge (Version 91.0.864.59) when trying to use it for the first time within an Angular 12

If you encounter the issue, please follow these steps using the latest version 91.0.864.59 of the Edge browser: https://stackblitz.com/edit/angular-ivy-zbvzap?file=src/app/app.component.html Click on the print button. Close the print dialog. Click on the ...

Having trouble decoding a JSON string with slashes?

Can someone shed some light on the reason behind this phenomenon? var_dump(json_decode(stripslashes(json_encode(array("O'Reiley"))))); // array(1) { [0]=> string(8) "O'Reiley" } var_dump(json_decode(stripslashes(json_encode(array("O\&ap ...

How can I use PHP and JavaScript to iterate through a <select> / <option> list and gather the values?

I am working on a project where I have a group of options within a selection dropdown and my goal is to utilize JavaScript to deselect all chosen values, gather them into a string, and then send it over to my PHP script. ...

I am configuring Jest in my Vite and TypeScript-powered React project

I am having trouble with the relative path of the file I imported in App.test.tsx. It keeps showing me this error message: Cannot find module '@/components/items/card.tsx' from 'src/__tests__/App.test.tsx' Below is the code snippet: // ...

What steps can I take to ensure that my server is accessible to all users?

After successfully creating a chat server using Node.JS and hosting it on my LocalHost (127.0.0.1), I realized that only I have access to the chat. To make the chat server accessible to everyone, I want to deploy it on my real server. The real server URLs ...