What is the best way to categorize an array based on a specific key, while also compiling distinct property values into a list

Suppose there is an array containing objects of type User[]:

type User = {
   id: string;
   name: string;
   role: string;
}; 

There may be several users in this array with the same id but different role (for example, admin or editor). The goal is to convert the above array into an array of objects defined as:

type GroupedUser = {
   id: string;
   name: string;
   roles: string[];
}; 

In this new array structure, for any user sharing the same id, their roles will be combined and stored in an array.

Answer №1

To accomplish this task, you can utilize the Array#reduce method, which converts an array into a single value:

interface Person {
  id: string;
  name: string;
  profession: string;
}

interface GroupedPerson extends Omit<Person, "profession"> {
  professions: Array<Person["profession"]>;
}

const people: Array<Person> = [
  {
    id: "1",
    name: "John Doe",
    profession: "engineer",
  },
  {
    id: "2",
    name: "Jane Smith",
    profession: "manager",
  },
  {
    id: "3",
    name: "Alice Johnson",
    profession: "artist",
  },
];

const groupedPeople = people.reduce<Array<GroupedPerson>>(
  (groupedPersons, currentPerson) => {
    const matchingGroupedPersonIndex = groupedPersons.findIndex(
      (g) => g.id === currentPerson.id
    );

    if (matchingGroupedPersonIndex === -1) { // Add the person to the array if not encountered yet
      groupedPersons.push({
        id: currentPerson.id,
        name: currentPerson.name,
        professions: [currentPerson.profession],
      });
    } else { // Otherwise, add their profession
      groupedPersons[matchingGroupedPersonIndex].professions.push(currentPerson.profession);
    }

    return groupedPersons;
  },
  []
);

groupedPeople will contain the following structure:

[
  {
    "id": "1",
    "name": "John Doe",
    "professions": [
      "engineer"
    ]
  },
  {
    "id": "2",
    "name": "Jane Smith",
    "professions": [
      "manager"
    ]
  },
  {
    "id": "3",
    "name": "Alice Johnson",
    "professions": [
      "artist"
    ]
  }
] 

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 are some ways to design scrollbars with a Google Wave-like style?

Is there a way to design scrollbars similar to the ones found in Google Wave? They seem to save space and have an appealing look. I am interested in implementing these customized scrollbars on a div element, just like how Google Wave utilizes them. (im ...

Problem encountered when utilizing the jQuery method .load()

Currently, there is an issue on my website where I am trying to load the content of a PHP file into a <div>. After ruling out any server-side problems, I have come to seek help with this question: Is there anything incorrect in the following code? & ...

Modify the getAttribute value if it is null

I'm currently working on a project where I need to compile the answers selected in a quiz into a document. However, I've encountered a roadblock when certain questions are skipped based on previous responses. This leads to an error message: Un ...

Merge HTML documents with this powerful JavaScript library

Our team has developed an email generator that creates HTML emails based on specific parameters. Users can simply select or deselect options and the email will be regenerated accordingly. Occasionally, users may need to make minor manual changes to the co ...

Below are the steps to handle incorrect input after receiving only one letter:

H-I This is my input .centered-name { width: 80%; margin: auto; } .group { width: 100%; overflow: hidden; position: relative; } .label { position: absolute; top: 40px; color: #666666; font: 400 26px Roboto; cursor: text; transit ...

Java code to extract and delete a section of a website on a webpage

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ View view = inflater.inflate(R.layout.fwebview, container, false); webView = (WebView) view.findViewById(R.id.webView); String url = ge ...

Is it possible to integrate a personalized theme into react-dates?

Attempting to customize the styling of my react-dates DayPickerRangeController in Typescript using react-with-styles and Aphrodite. I have implemented the following code, mirroring the code found at https://github.com/airbnb/react-dates#interfaces: const ...

Unable to adjust the padding of the material UI Select component

I'm having trouble adjusting the padding of the Select component in order to align it with the size of my other text fields. Despite knowing that I need to make changes to nested components, I have yet to discover a viable solution. <div className ...

Issue with Vue.js - Double curly braces not rendering data on the page

I've recently delved into the world of vue.js Strangely enough, the double curly braces syntax doesn't seem to be rendering for me. However, when I utilize the v-text directive, everything falls into place. Here's a snippet of my code: HTM ...

Discovering the parameters at your disposal within a callback function can be easily achieved in JavaScript and MongoDB

Being new to JavaScript and web development, I've been self-studying but have encountered many roadblocks. Currently, I'm struggling with understanding functions with callback functions and their parameters. The documentation I've read so f ...

Angular variable resets to initial value after modification

Currently, I am utilizing ui-router to handle the state management for the admin segment of a project. The admin area includes the ability to browse through various categories. In this category management module, I am working on implementing a breadcrumb l ...

Confirm the Keycloak token by checking it against two separate URLs

In my system, I have a setup based on Docker compose with back-end and front-end components. The back-end is developed using Python Flask and runs in multiple docker containers, while the front-end is coded in TypeScript with Angular. Communication between ...

Require using .toString() method on an object during automatic conversion to a string

I'm interested in automating the process of utilizing an object's toString() method when it is implicitly converted to a string. Let's consider this example class: class Dog { name: string; constructor(name: string) { this.name = na ...

Import several image files using AngularJS

I recently came across a helpful tutorial that demonstrates how to upload pictures from your local computer using AngularJS directives. As a newcomer to Angular, I followed the instructions but now I'm stuck on modifying it to display the selected ima ...

How can we create a two-dimensional image with random dimensions using Math.random?

I am struggling to create a variety of flowers with different sizes from an Array. The issue I'm facing is that every time I click to add a new flower, it changes the size of all existing flowers as well. What I would like is for each added flower to ...

Angular: Effective communication between components through routing and Observable binding ultimately results in the advancement of ngtsc(233

I designed an Angular Component named "crear-pedido" that exhibits a catalog of items (using row of products) and my aim is for the user to have the ability to click on the values in the ID column and navigate the application to a subordinate component kno ...

What could be causing req.params to come back as undefined?

I have reviewed two similar questions here, but none of the suggestions in the comments seem to be resolving my issue. app.get('/:id', function(req,res) { console.log(req.params.id); }); app.get('/:id', function(req, res) { db.que ...

"Emphasize menu items with an underline as you navigate through the

I am using Gatsby with React and have a navigation menu with links. I would like to make it so that when a link is clicked, a border bottom appears to indicate the current page, rather than only on hover. <ul className="men" id="menu"> ...

Adding elements to a two-dimensional array using AngularJS

How can I assign the value of an input to tasks.name and automatically set status: false when adding a new item to the $scope.tasks array? HTML <input type="text" ng-model="typeTask"> <button ng-click="updateTasks()">Add task</button> ...

What is the most efficient method for encoding and decoding extensive volumes of data for a JavaScript user?

Currently, I am in the process of developing a standalone Javascript application using Spine and Node.js to create an interactive 'number property' explorer. This application allows users to select any number and discover its various properties s ...