JavaScript: Organize an array of objects into separate sections based on a specific field

Presented below is a set of data:

const dataSet = [
  {
    id: '1',
    name: 'River',
    address: 'Terminal A',
    type: 'OTHER',
    code: null,
    targetArrivalStep: 30,
    disabled: true,
  },
  {
    id: '2',
    name: 'Afer',
    address: 'Afer train station',
    type: 'TRAIN_STATION',
    code: 'MTS',
    targetArrivalStep: 0,
    disabled: false,
  },
  {
    id: '3',
    name: 'Fidel',
    address: 'HHH',
    type: 'OTHER',
    code: '',
    targetArrivalStep: 0,
    disabled: false,
  },
  {
    id: '5',
    name: 'Train station',
    address: 'Patrick str.',
    type: 'TRAIN_STATION',
    code: null,
    targetArrivalStep: 0,
    disabled: false,
  },
  {
    id: '7',
    name: 'qqq',
    address: 'qqq',
    type: 'BUS_STATION',
    code: null,
    targetArrivalStep: 60,
    disabled: false,
  },
];

The objective is to categorize this data by the type.

Here is the expected result:

const results = [
  {
    type: 'OTHER',
    data: [
      {
        id: '1',
        name: 'River',
        address: 'Terminal A',
        type: 'OTHER',
        code: null,
        targetArrivalStep: 30,
        disabled: true,
      },
      {
        id: '3',
        name: 'Fidel',
        address: 'HHH',
        type: 'OTHER',
        code: '',
        targetArrivalStep: 0,
        disabled: false,
      },
    ],
  },
  {
    type: 'TRAIN_STATION',
    data: [
      {
        id: '2',
        name: 'Afer',
        address: 'Afer train station',
        type: 'TRAIN_STATION',
        code: 'MTS',
        targetArrivalStep: 0,
        disabled: false,
      },
      {
        id: '5',
        name: 'Train station',
        address: 'Patrick str.',
        type: 'TRAIN_STATION',
        code: null,
        targetArrivalStep: 0,
        disabled: false,
      },
    ],
  },
  {
    type: 'BUS_STATION',
    data: [
      {
        id: '7',
        name: 'qqq',
        address: 'qqq',
        type: 'BUS_STATION',
        code: null,
        targetArrivalStep: 60,
        disabled: false,
      },
    ],
  },
];

My current approach involves using the reduce method, but I am looking for a solution that does not involve mutating reduce arguments. Is there an alternate method to achieve this?

Answer №1

According to the comments, it is acceptable to modify the accumulator since it is newly created for each function call and only changes internally, without any external interruptions. This means that from an external perspective, your solution functions as a pure function without any side effects.

However, for demonstration purposes, you could rework your solution in a declarative manner using some advanced destructuring techniques:

const result = data.reduce((c, item) => ({...c, [item.type]:[...c[item.type] ?? [], item]}), {});

Explanation:

const result = data.reduce(
  (c, item) => ({              // Create a new object
    ...c,                      // Copy previous object properties
    [item.type]: [             // Replace current type group
      ...(c[item.type] ?? []), // Copy existing items of that group (or an empty array)
      item                     // Add the current item
    ] }),
  {}
);

It seems evident, however, that your original solution is more readable and therefore superior.

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

Comparing NextJs hydration with using the client-side approach

Currently exploring the ins and outs of NextJs to grasp its fundamental features. It is my understanding that by default, NextJs components operate on the server-side and utilize Hydration to enable interactivity shortly after displaying pre-rendered HTML ...

Pictures acting erratic following the implementation of two setTimeout functions

I encountered an issue while developing a pong game using html/css/javascript. Everything was going smoothly until I introduced a second setTimeout() function. Here is the snippet of my html code: <!DOCTYPE html> <html> <head> <scrip ...

"Can you provide instructions on placing a span within an image

I am trying to figure out how to insert a <span> into an <image>, similar to the effect on the page . However, I do not want this effect to occur on hover(), but rather on click(). My goal is to insert "data-title" into the <span> and hav ...

How to check Internet upload speed in Angular without using a backend server?

I need help uploading a file to a folder within my Angular app's directory while it is running on localhost. I have been unable to find a solution that doesn't involve using backend technologies. For instance, I simply want to upload an image fi ...

What are the solutions for fixing a JSONdecode issue in Django when using AJAX?

I am encountering a JSONDecodeError when attempting to send a POST request from AJAX to Django's views.py. The POST request sends an array of JSON data which will be used to create a model. I would greatly appreciate any helpful hints. Error: Except ...

Effortless JavaScript function for retrieving the chosen value from a dropdown menu/select element

I've figured out how to retrieve the value or text of a selected item in a dropdown menu: document.getElementById('selNames').options[document.getElementById('selNames').selectedIndex].value In order to simplify this code, I&apos ...

What is the most effective method for handling extremely large Long numbers in Ajax?

When it comes to Javascript, all numbers are represented as double-precision floating-point. This can result in a loss of precision when handling numbers that exceed the 64 bit Java Long datatype limit of 17 digits. For instance, a number like: 7143412520 ...

Text displayed in dropdown when selecting autocomplete option from Material UI

I'm facing a problem with the Material UI's Autocomplete Component. The issue is that the value is being shown instead of the text element. My data source format looks like this: [{value: 'someValue', text: 'My Text'}, {value ...

Can a client-side React component or application be hosted on a server-side Express route?

Currently, I have a Node/Express backend that utilizes Pug.js to render various server-side routes for a basic, static website. In React.js, I have developed an interactive "builder" component through CRA, enabling visitors to configure products interacti ...

What is the best way to implement CSS properties on Material UI components?

I've recently started exploring Material UI, but I'm having trouble understanding how the spacing properties function. I'm trying to utilize the "spacing" feature for various elements, but it appears that it only works for "Box" components a ...

How to implement caching using XMLHttpRequest?

As someone who has primarily relied on jQuery's AjAX method, I am relatively new to using XMLHttpRequests. However, due to performance concerns in a web worker environment, I now find myself having to resort to the classic XMLHttpRequest. Currently, ...

Using JavaScript, learn how to extract query parameters and encoded information from a URI

I am looking for a specific module in order to extract information from query parameters within a URL. The format includes 2 query parameters and an encoded piece of data. Do I need to use split functions or is there a more direct approach available? Sampl ...

Unable to retrieve data from AJAX request in the AJAX success function

I've seen this question asked multiple times and I've gone through several answers regarding callbacks, but I'm still struggling to understand how to apply it to my specific situation. I have an ajax function that is being called from the su ...

Using TypeORM in Javascript to create routes efficiently

After examining the TypeORM websites examples, I noticed that some of them demonstrate routing usage using TypeScript. Given that TypeORM has the capability to use JavaScript instead of TypeScript, I am seeking guidance on how to implement Express routing ...

Exploring variations in error handling for JavaScript promises in Node.js depending on whether the error is synchronous or asynchronous

Exploring the nuances of promise error handling for thrown errors and exceptions in the promise executor, particularly in comparison to reject, within a node.js context. Differences in handling between reject and throw/exceptions are evident. Some source ...

Changing HTML dynamically does not trigger the ng-click event within ng-bind-html

I have developed a custom directive that can display messages along with rendering HTML content that may contain Angular attributes like buttons, anchor tags with ng-click attribute, and more. index.html: <ir-error-panel status="status"></ir-err ...

Is there a beginner's pack or trial version available for utilizing TypeScript with IBM Cloud Functions / OpenWhisk?

While working on developing actions in IBM Cloud Functions, I have been primarily using Node.js / Javascript and Python for coding. However, I haven't come across specific instructions on how to incorporate TypeScript into IBM Cloud Functions. I am c ...

Is it possible to create a dedicated page in Next.js using static site generation (SSG)?

The static-site generation (SSG) feature of Nextjs allows for fetching data at build time, resulting in pre-rendered pages using getStaticProps and getStaticPaths. Imagine having a blog with numerous articles that remain static, while some may be updated ...

Changes made to the V-model property will only be reflected after the page is refreshed

I have encountered a situation with two checkboxes that need to reflect the values of watched computed properties. While I can observe reactive changes in my Vue extension when these properties are altered, the updated states of the checkboxes only appear ...

Steps for showing personalized validation error messages in Angular 7

Is there a way to highlight the input field of a form with a red border and display the message Password is invalid when a user types in a password that does not match the set password? I have managed to see the red border indicating an error when I enter ...