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

The issue with the jQuery class change not being triggered in Internet Explorer seems to be isolated, as Chrome and

This little jQuery script I have is supposed to show a fixed navigation menu once the page has been scrolled below 200px, and then change the class on each menu list item to "current" when that section reaches the top of the viewport. The issue is that th ...

Is it possible to manage how many times a functional react component re-renders based on changes in its state?

For my practice e-commerce app, I have a functional component called "Shop" with two states: [products, setProducts] = useState([10ProductObjects]) and [cart, setCart] = useState([]) Upon the initial render, 10 products are loaded and each Product compone ...

Tips for executing a JavaScript function within a secure sandbox environment

My current setup involves an application server developed in JavaScript (node.js) where I receive JS function code as input from a web browser. Now, my goal is to execute this function on the server without any interference with other processes. I am look ...

What is the method for combining two box geometries together?

I am looking to connect two Box Geometries together (shown in the image below) so that they can be dragged and rotated as one object. The code provided is for a drag-rotatable boxgeometry (var geometry1). What additional code do I need to include to join t ...

Tips for creating a TypeScript function that is based on another function, but with certain template parameters fixed

How can I easily modify a function's template parameter in TypeScript? const selectFromObj = <T, S>(obj: T, selector: (obj: T) => S): S => selector(obj) // some function from external library type SpecificType = {a: string, b: number} co ...

Converting a functional component into a class-based component

I am in the process of converting a functional based Component to a class-based Component and creating a PrivateAuth Component. Here is the original PrivateAuth functional Component. function PrivateRoute({ component: Component, ...rest }) { return ( ...

Is there a way to utilize redux to trigger the opening of my modal when a button is clicked?

I'm facing a challenge with opening my modal using redux when clicking <CheckoutButton/>. Despite my efforts, the modal keeps appearing every time I reload the browser. I've reviewed my code but can't pinpoint the issue. What am I doin ...

The metro bundler is facing an unexpected glitch and is stuck in the terminal, failing to load

Recently, I've been using explo-cli to work on a react native project. Everything was running smoothly until today when I encountered an error stating that it couldn't find module './iter-step'. Before this, there was also an issue with ...

Error: Module '/node_modules/.vite/deps/react-pro-sidebar.js?v=913080ef' does not export 'ProSidebar' as requested

Using the pro-side-bar library in React is causing an issue for me. When I run the code, the console shows the following error using the dev tools: Uncaught SyntaxError: The requested module '/node_modules/.vite/deps/react-pro-sidebar.js?v=913080ef& ...

Is it possible to use function declaration and function expression interchangeably?

As I dive into learning about functions in Javascript, one thing that's causing confusion for me is the difference between function declaration and function expression. For example, if we take a look at this code snippet: function callFunction(fn) { ...

Keep the list up-to-date by adding new items promptly

Utilizing Angular 7, I have implemented the following service (Click here for StackBlitz Example): @Injectable({ providedIn: 'root' }) export class TodoService { todos: BehaviorSubject<Todo[]> = new BehaviorSubject([ { id: 1, tit ...

Top method for organizing and filtering tables in Laravel on the client side?

In my Laravel web application, I have multiple tables with MySQL data stored. I want to provide users with the ability to sort and filter data on any column header dynamically, all processed on the client side. Although Laravel does not come with this feat ...

Modifying the value of a local variable results in a corresponding adjustment to the original global variable's value

Within my Node.js program, I have set up an array named "list" in the routes section. This array is populated with values from a function defined in the model. The code for this route looks like: var express = require('express'); var router = ex ...

Steps to Create an HTML Text Box that cannot be clicked

Does anyone know of a way to prevent a text box from being clicked without disabling it or blocking mouse hover events? I can't disable the text box because that would interfere with my jQuery tool tips, and blocking mouse hover events is not an opti ...

Error: The function res.getHeader is not recognized within the Next.js API environment

I am currently working on a web application using NextJS 13, TypeScript, Next Auth v4, Prisma (using SQLite for development), and OpenAI. While accessing the API endpoint, I encountered an error in the console with the following message: error - TypeError ...

Pictures will be displayed briefly for 1 second prior to the initiation of the JavaScript animation

I recently built a website using gatsby.js and incorporated bounce.js to animate some images on the page. Bounce.js is a JavaScript library that offers DOM animation functionalities. Although everything appears fine when I view the site locally, once I de ...

Enhance a Javascript object by dynamically introducing new elements

I am currently working on a webpage using HTML and jQuery. My goal is to create a form where users can enter an email address in a textbox, and when they click a button, the email should be added to an object that displays all the emails entered so far. Th ...

Experiencing challenges in integrating fundamental Javascript elements on a chat page

My chat page skeleton is in place, but I'm facing challenges in connecting all the pieces. My goal is to send messages to the server whenever a user clicks 'send', and to update the displayed messages every 3 seconds. Any insights, tips, or ...

Using JavaScript to modify the text of a label seems to be a challenging

UPDATE: After carefully reviewing my code once again, I have identified the issue. The problem lies in the positioning of a certain function (unfortunately not included here), but rest assured that I have rectified it! Allow me to provide a brief summary ...

Searching for a value within an array of objects using JavaScript: The ultimate guide

Similar Question: Locate specific object by id within a JavaScript objects array What is the best way to determine if a value exists in a given JavaScript array? For instance: var arr = [ {id: 1, color: 'blue'}, {id: 2, colo ...