Select a key value from an array and categorize the items based on that value

I'm trying to organize an array of objects by a specific value and use that value as a key for the rest of the object values. Here's an example:

{
  0: {prize: "Foo", first_name: "John", last_name: "Smith"},
  1: {prize: "Foo", first_name: "Mary", last_name: "Smith"},
  2: {prize: "Bar", first_name: "Jane", last_name: "Doe"},
  3: {prize: "Bar", first_name: "Jack", last_name: "Jones"},
  4: {prize: "Foo", first_name: "Judy", last_name: "Alvarez"}
}

The desired outcome is this structure:

{
  Foo: [
   {first_name: "John", last_name: "Smith"},
   {first_name: "Mary", last_name: "Smith"},
   {first_name: "Judy", last_name: "Alvarez"}
  ],
  Bar: [
   {first_name: "Jane", last_name: "Doe"}, 
   {first_name: "Jack", last_name: "Jones"}
  ]
}

I tried using TypeScript with a code snippet I found, but it didn't get me exactly what I needed:

console.log(
  _.chain(res.data)
  .groupBy("prize")
  .map((value: any, key: any) => ({prize: key, winners: value}))
  .value()
);

How can I adjust my code to achieve the desired format effectively? Is there a different approach I should take?

This seems like a common issue that may have been addressed before, but I'm having trouble articulating my problem in searches. Apologies if this is a duplicate question.

Answer №1

To efficiently organize the object, you can destructure it and group by the prize attribute within a single iteration loop.

const
    data = [{ prize: "Foo", first_name: "John", last_name: "Smith" }, { prize: "Foo", first_name: "Mary", last_name: "Smith" }, { prize: "Bar", first_name: "Jane", last_name: "Doe" }, { prize: "Bar", first_name: "Jack", last_name: "Jones" }, { prize: "Foo", first_name: "Judy", last_name: "Alvarez" }],
    result =  data.reduce(
        (r, { prize, ...rest }) => ((r[prize] ??= []).push(rest), r),
        {}
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

To iterate through the original object, you can utilize the for...in loop. In this case, the prize property is used as the new key for the resulting object. The object to be stored in the key's array is saved as a variable named t, while the key itself is stored in a variable named k.

 var k = obj[i].prize
 var t = obj[i]

Below is an excerpt showcasing a functional demonstration.

var obj = {
  0: {prize: "Foo", first_name: "John", last_name: "Smith"},
  1: {prize: "Foo", first_name: "Mary", last_name: "Smith"},
  2: {prize: "Bar", first_name: "Jane", last_name: "Doe"},
  3: {prize: "Bar", first_name: "Jack", last_name: "Jones"},
  4: {prize: "Foo", first_name: "Judy", last_name: "Alvarez"},
}

const constructObj = () => {
  var newObj = {}
  
  for (var i in obj){
    var k = obj[i].prize
    var t = obj[i]
    // uncomment line below to include all keys
    // delete t.prize
    if (newObj[k]){
      var vals = newObj[k]
      vals.push(t)
    } else {
      newObj[k] = [t]
    }
  }
  return newObj
};

var final = constructObj()

console.log(final)

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

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 ...

Encountered issues retrieving data using a combination of Docker, MySQL, Express, and TypeScript

After successfully creating a todo-app using Node.js, TypeScript, and MySQL, I encountered an error when trying to run the app on a Docker Container. Failed to load resource: net::ERR_NAME_NOT_RESOLVED TypeError: Failed to fetch at getTodos (ListTodo.t ...

Generating a File that Imports Components and Instantly Exports Them Once More

Having trouble with this code. Initially, I had: // file 1 import Box from '@/components/Box' import Popup from '@/components/Popup' const MDXComponents = { Box, Popup } // using MDXComponents somewhere in file 1 Now, to manage t ...

Transform complex nested object structure

What is the optimal method to transform ... ? const obj = { A: { B: [0, 0, 0, 0] }, D: { B: [0, 0, 0, 0], C: [0, 0, 0, 0] } } into const obj = { "A - B": [0, 0, 0, 0], "D - B": [0, 0, 0, 0], "D - C": [0, 0, 0, 0] } Thank you for yo ...

Async/Await function is not behaving as intended

Our current approach involves storing short strings as keys. These keys are linked to longer values, which serve as labels. I am attempting to update the corresponding longer value for each key. However, a problem arises where console.log(record) always ...

Sending data when button is clicked from Google Apps Script to sidebar

I have been attempting to pass a list that includes both the start cell and end cell of the active range. I want to then assign each value from this list to separate input fields. document.getElementById("btn-get-range").addEventListener('click&apo ...

I am interested in extracting specific data from the JSON response

I am trying to extract the value of the message parameter under the messages array where the parameter name is equal to documentId (highlighted in bold below). However, the code I have tried so far does not achieve this as needed. dynamic obj = JsonConver ...

Utilizing Typescript to Inject Generics and Retrieve the Name of an ES6 Module

I am currently working on developing a versatile repository using: Typescript ES6 Angular 1.x However, I am facing challenges in determining the correct way to inject the Entity and retrieve its module name. The main reason for needing the name: I adh ...

Tips for sending Form Data and additional information via AJAX

I'm struggling with sending HTML form data using AJAX while also trying to send additional data in the same POST call. Has anyone done this before? $('#HTMLConForm').on('submit', function (e) { e.preventDefault(); ...

Is it possible to include additional information when creating a subscription for a customer on Stripe using Node.js

I am facing an issue with adding metadata to the customer object during the creation of a new subscription/customer using Stripe. The problem lies in the fact that the metadata is not being saved to the customer object. I have checked the logs/events in St ...

Determine the position of elements in a single column of arrays based on another column of arrays

I am faced with a dataframe containing two columns column_1 column_2 ["apple","orange"] ["orange", "apple"] ["banana"] ["apple"] My objective is to create a new c ...

Trouble with saving $http get response data to a scope variable

Here is the code snippet that is facing an issue in assigning return values to the scope variable. app.factory("appService",function($http){ var promise; var lists = { async: function() { var promise = $http.get("http://localhost:81/hrms/pub ...

Learn how to subscribe to Azure Event Grid using Angular without the need for a backend service layer

I am currently working on an Angular project and I am looking to set up Azure Event Grid subscription directly from the client-side without the need for a backend service. After exploring different options, I have not yet found a straightforward solution. ...

Enhance the numerical value displayed in jQuery UI tooltips

I have folders with tooltips displaying text like '0 entries' or '5 entries' and so on. I am looking for a way to dynamically update this tooltip number every time an item is added to the folder. The initial count may not always start a ...

A guide on utilizing ng-repeat to iterate through array values in Views

Need help with using ng-repeat on array values within an ng-repeat in VIEWS? The second ng-repeat is not functioning properly. Here is the value of generalDocument.documents: ["14-10-2015.xls","15-10-2015.xls","16-10-2015.xls"] <div class="box-body ...

The editor is locked and choices are displayed in a vertical orientation

I'm currently experimenting with using draft js in my project to create a wysiwyg editor. However, I've encountered an issue where the editor appears vertically instead of horizontally when I load the component. Any idea why this might be happen ...

How to reference the "this" property in TypeScript when using the <svelte:component> tag

In my Svelte project, I am working on a portal system where a component is passed using a store to display at a higher level in the component tree. My current struggle lies in typing the store correctly. I attempted to declare it like this: const modalCom ...

Changing the value of a focused input in the Android browser using programming methods

Is it possible to enforce a specific date format (00/00/0000) on a text input field? The input field has a maxlength of 10 characters, and validation is being handled separately. Below is the jQuery code snippet I am currently using: $(function( ...

Having trouble displaying the selection menu when using Angular Strap?

//test.js const dropdownMenu = document.querySelector('.dropdown-menu'); dropdownMenu.addEventListener('click', (event) => { alert(`You clicked on ${event.target.textContent}`); }); // index.html <div class="dropdown"> ...

Make sure that the click event listener is set up on the anchor element so that it also affects its children

Currently, I have implemented a click event listener on my anchor elements. However, the anchors contain a span element within them, and the event listener does not function properly if you click on the span inside the anchor. document.addEventListene ...