Categorize an array of objects based on a key using JavaScript

I searched extensively for solutions online, but I still can't seem to make it work and I'm unsure why.

Here is an array with objects:

array =[
   {
      "name":"Alex",
      "id":0
   },
   {
      "age":20,
      "id":0
   },
   {
      "name":"John",
      "id":1
   },
   {
      "age":30,
      "id":1
   }
]

My goal is to group them based on their id, resulting in the following outcome:

array =[
   [
      {
         "name":"Alex",
         "id":0
      },
      {
         "age":20,
         "id":0
      }
   ],
   [
      {
         "name":"John",
         "id":1
      },
      {
         "age":30,
         "id":1
      }
   ]
]

I came across several solutions that dealt with a similar problem, so I attempted one, but I can't figure out why it's not functioning as expected.

 array.reduce((a, value) => {
       a[value.id] = [...a[value.id] || [], value];
        return a;
    }, [])

If anyone could shed some light on this issue, that would be greatly appreciated.

Answer №1

One reason for this issue is that the value.index property does not exist, causing it to always be undefined.

To resolve this, simply replace value.index with value.id, and the code will function correctly.

const array = [{
    "name": "Alice",
    "id": 0
  },
  {
    "age": 25,
    "id": 0
  },
  {
    "name": "Bob",
    "id": 1
  },
  {
    "age": 35,
    "id": 1
  }
];

const output = array.reduce((accumulator, value) => {
  accumulator[value.id] = [...(accumulator[value.id] || []), value];
  return accumulator;
}, []);
console.log(output);

Answer №2

You have mistakenly used the wrong key - index. It should be corrected to id

const items = [{
    "name": "Alex",
    "id": 0
  },
  {
    "age": 20,
    "id": 0
  },
  {
    "name": "John",
    "id": 1
  },
  {
    "age": 30,
    "id": 1
  }
]

const result = items.reduce((accum, item) => {
  accum[item.id] = [...accum[item.id] || [], item];
  return accum;
}, [])

console.log(result);

Answer №3

When considering your specific scenario, it's worth noting that there isn't an "index" attribute associated with your objects. As a result, invoking value.index will yield undefined. If your intention is to utilize the id fields as the index for the final array (as indicated by the reduce function you're attempting), consider employing the following approach. Be aware, however, that if your object ids are not consecutive starting from 0, your final array may contain null values. To address this, you can eliminate these null values by implementing something akin to array.filter((el) => el ); on your final array.

array.reduce((a, value) => {
  if (a[value.id]) {
    a[value.id].push(value);
  } else {
    a[value.id] = [value];
  }
  return a;
}, []);

Answer №4

There was a small error in your initial question, but you quickly corrected it with an edit. If you want to ensure compatibility with any ID values (as mentioned in a comment where IDs like 0 and 1 are considered valid and early array indices), then using a Map and retrieving its values() is advisable:

const array = [{
    "name": "Alice",
    "id": 90
  },
  {
    "age": 25,
    "id": 90
  },
  {
    "name": "Bob",
    "id": 110
  },
  {
    "age": 35,
    "id": 110
  }
]

const map = array.reduce((acc, val) => {
  acc.set(val.id, [...acc.get(val.id) || [], val]);
  return acc;
}, new Map())
const result = Array.from(map.values());

console.log(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

I possess a collection of timed images that I aim to employ jQuery for seamlessly transitioning between them

My script is functioning as intended, but I would like to incorporate jQuery fade-in/fade-out effects to transition between images without making significant changes to the existing code. <script language="JAVASCRIPT" type="text/javascript"> var ad ...

Why does the API in Next Js get triggered multiple times instead of just once, even when the strict mode is set to false?

React Query Issue I am currently facing an issue with React Query where the API is being triggered multiple times instead of just once when the selectedAmc value changes. I have tried setting strict mode to false in next.config.js, but that didn't so ...

Using jQuery to implement AJAX file uploads

Currently, I am facing a challenge. I have multiple forms on a single page that are being submitted to the backend asynchronously via ajax. Some of these forms require a file upload without interrupting the process, so it needs to be handled asynchronousl ...

How to incorporate a delay in ng-repeat using AngularJS

Currently, I am facing an issue with my ng-repeat block. In this block, I am generating elements based on data received from an ajax request, which sometimes causes a delay due to latency. Within the same block, I have implemented a filter to remove unwant ...

Capture data from a Telegram bot and store it in a Google Sheet

I am trying to use a spreadsheet through a Telegram bot as a TODO list so that when I input something on my phone, it is saved in the spreadsheet. (I'm following this tutorial https://www.youtube.com/watch?v=XoTpdxbkGGk, which seems accurate with Goog ...

Why is the decision made to simply remove an item? Is there an option to instead choose and delete the specific item?

I am facing an issue with my form where I have a function to dynamically add inputs using "append" and another button to remove the inputs added. When I use the "last-child" selector to delete the last generated div, the remove button stops working and I a ...

What is the process for invoking a server-side Java function from HTML with JavaScript?

Can someone help me figure out the best way to invoke a Java method from HTML (I'm working with HTML5) using JavaScript? I attempted using Applets but that approach didn't yield any results. My goal is to extract the value from a drop-down menu i ...

Exploring the 3D Carousel Effect with jQuery

After creating a 3D carousel using jQuery and CSS3, I am looking to enhance it with swiping support. While there are plenty of libraries available for detecting swipes, I specifically want the carousel to start rotating slowly when the user swipes slowly. ...

Is it normal for Tailwind animation to loop twice when transitioning between pages in Next.js?

I'm currently utilizing react-hot-toast for displaying alerts and animating them during page transitions. The animation involves a double fade-in effect when transitioning between pages. In my project, I've integrated tailwindcss-animate within ...

The Plupload internal version seems to be incorrect. The file is labeled as 2.3.9, however, the actual version within the file is 2.3

We recently identified a security vulnerability issue with plupload 2.3.6 being deemed as vulnerable. To address this, we downloaded version 2.3.9 from the official Plupload website here: Upon inspection, we found that the zip file is labeled as 2.3.9, bu ...

Contrast between the $q constructor and promise interface

Can you explain the concept of a promise interface in angular JS? Furthermore, what exactly is a $q constructor? In which scenarios are these functionalities utilized and how do they differ from each other? I have looked into multiple resources but st ...

Switch off any other currently open divs

I'm currently exploring a way to automatically close other div's when I expand one. Check out my code snippet below: $( document ).ready(function() { $( ".faq-question" ).click(function() { $(this).toggleClass('open'); $(this ...

Setting a Value?

Within the services.js/Cordova file, I am encountering an issue with the following code: .factory('GCs', ['$http', function($http) { var obj= {}; $http.post("mydomina.com?myrequest=getbyid", { "id": "1"} ) ...

Using Node.js to implement pagination with the POKEapi through a loop

Recently, I've been experimenting with the POKEapi to display information on 150 different pokemons. This is my first attempt at creating a node.js app as I'm just starting to learn javascript. The challenge I'm facing now is implementing ...

Is it possible to incorporate an editable text feature within react-moveable? (Allowing for both dragging and editing capabilities)

In React Movable box, the text can be dragged with a left click and edited with a right click using the "contentEditable" attribute. However, on smartphones, editing seems to be disabled and only dragging is possible. <div className="move ...

Steps for integrating the -toDataURL() method on a node.js server

As a newcomer to webgl implementation in my project, I am facing an issue with the .toDataURL() function while using the node-webgl wrapper on the server side. The error I encounter states that .toDataURL() is undefined. More information on this error can ...

Show information in a React Native element | Firebase

Just starting out with react native and struggling to display data in a component? You're not alone! I'm having trouble too and would love some guidance on how to destructure the data for display. Any tips? import React,{useState,useEffect} from ...

Developing a random string generator using Java within an Android app

Currently, I am working on developing a password generator (random string generator) that will eventually be integrated into a database. However, I encountered an issue where the app terminates with the error message "java.lang.ArrayIndexOutOfBoundsExcep ...

Incorporating list items in a React component is not functioning as expected

When I console.log(this.props), here are my props: list:Array(1): {user: "Jack Nicholson", userid: "5b684ed8d3eb1972b6e04d32", socket: "1c0-Jb-kxe6kzPbPAAAD"} However, despite mapping through my list and using the component <UserItem user={user.user} ...

Encountering an error in AngularJS: Issue with require(...) function, along with a runtime error in Node

I have been working on a code similar to the one available here However, when I try to run node web.js, I encounter a TypeError: require(...) is not a function What could be causing this error? Where might the issue lie? Below is my current web.js set ...