Generating an array of keys from duplicated values in Typescript

My data is structured in the following array format:

  {
    itemTitle: 'value example',
    itemType: 'value example',
    itemDescription: 'value example',
    itemFamily: 'Asset',
  },
  {
    itemTitle: 'value example',
    itemType: 'value example',
    itemDescription: 'value example',
    itemFamily: 'Asset',
  },
  {
    itemTitle: 'value example',
    itemType: 'value example',
    itemDescription: 'value example',
    itemFamily: 'Periodic',
  },
  {
    itemTitle: 'value example',
    itemType: 'value example',
    itemDescription: 'value example',
    itemFamily: 'Periodic',
  },

I am seeking to reformat this data into a key-value map, using itemFamily as the key. The transformed output should resemble this structure:

{ Asset:  
   [ { itemTitle: 'value example', 
       itemType: 'value example', 
       itemDescription: 'value example', 
       itemFamily: 'Asset' }, 
     { itemTitle: 'value example', 
       itemType: 'value example', 
       itemDescription: 'value example', 
       itemFamily: 'Asset' } ], 
  Periodic:  
   [ { itemTitle: 'value example', 
       itemType: 'value example', 
       itemDescription: 'value example', 
       itemFamily: 'Periodic' }, 
     { itemTitle: 'value example', 
       itemType: 'value example', 
       itemDescription: 'value example', 
       itemFamily: 'Periodic' } ] 
}

Any suggestions on how I can achieve this transformation?

Answer №1

Here's a sample code snippet for utilizing the reduce method:

const result = yourArray.reduce((accumulator, item) => {
  if (!accumulator[item.family]) { 
    accumulator[item.family] = [];
  }
  accumulator[item.family].push(item);
  return accumulator;
}, {});

Answer №2

To start off, the key is to eliminate any illegal states.

This means that the Asset property should only include elements from the Asset family. Refer to the type Result

type Family = 'Asset' | 'Periodic';

interface Item {
  itemTitle: string,
  itemType: string,
  itemDescription: string,
  itemFamily: string,
}
const data: Item[] = [
  {
    itemTitle: 'value example',
    itemType: 'value example',
    itemDescription: 'value example',
    itemFamily: 'Asset',
  },
  {
    itemTitle: 'value example',
    itemType: 'value example',
    itemDescription: 'value example',
    itemFamily: 'Asset',
  },
  {
    itemTitle: 'value example',
    itemType: 'value example',
    itemDescription: 'value example',
    itemFamily: 'Periodic',
  },
  {
    itemTitle: 'value example',
    itemType: 'value example',
    itemDescription: 'value example',
    itemFamily: 'Periodic',
  },
]

type Result = Record<string, Item[]>

const hasProperty = <Obj, Prop extends string>(obj: Obj, prop: Prop)
  : obj is Obj & Record<Prop, unknown> =>
  Object.prototype.hasOwnProperty.call(obj, prop);

const handleProperty = (acc: Record<string, Item[]>, elem: Item) =>
  hasProperty(acc, elem.itemFamily) ? [...acc[elem.itemFamily], elem] : [elem]

const builder = (data: Item[]) =>
  data.reduce<Result>((acc, elem) => ({
    ...acc,
    [elem.itemFamily]: handleProperty(acc, elem)
  }), {})

const result = builder(data)

Playground

Answer №3

This code snippet provides a solution using the reduce method:

const result = myArr.reduce((acc, val) => {
  acc[val.group] = [...(acc[val.group] || []), val];
  return acc;
}, {});

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

Why do I receive the error message "Error: Objects are not valid as a React child (found: [object Promise])" in NextJS13?

I'm feeling overwhelmed by this issue and unsure of how to resolve it. Here is the code that is causing trouble: 'use client' import React, { useState } from 'react' import AnimatedDiv from '../../../(shop)/(components)/animat ...

NodeJs encountered an issue due to the absence of defined username and data

I am facing an issue while trying to open the places.ejs file by clicking the submit button on the show.js page. Similar to how the show.ejs page opens upon clicking the submit button on the new.ejs file, I am encountering a reference error. Any assistance ...

Getting the value from a .sh (Shell Script) file in React: How to do it?

There is a .sh file that contains the following code: echo "Hello" This code produces the output: Hello The question at hand is: I am trying to extract the output from the .sh file and integrate it into my React application. After exploring various ...

Panel that collapses and increments its ID each time within my loop

I have a Collapsible Panel with this header, <div id="CollapsiblePanel1" class="CollapsiblePanel"> <div class="CollapsiblePanelTab" tabindex="0">Comments</div> <div class="CollapsiblePanelContent"> Content &l ...

Click anywhere outside the sidemenu to close it

I want the menu to behave like the side menu on Medium. When the side menu is open and the user clicks outside of #sidebar-wrapper, the side menu should close. Currently, I have to click the toggle X to close the menu. html <a id="menu-toggle" href="# ...

Unable to click, but can only be activated by touchstart or mousedown

Is it possible to bind a 'click' event to a paragraph? Here is the function I am using: $(document).on('touchstart mousedown',"p span.text", function(e) { console.log('I was clicked'); *more code here* }); When I ...

Instructions for saving a binary file on the client using jQuery's .post function

I am working with a handler that has the following code: HttpRequest request = context.Request; HttpResponse response = context.Response; if (request["Type"] != null) { try { string resultFile = null; ...

Updating the color of specific buttons using ngFor in Typescript and Angular 8

I have successfully implemented a feature where text is displayed word by word using an ngFor directive. Within the ngFor loop, there is an if-else statement that determines whether each word should be displayed as a <span> or a <button>. Now, ...

Unable to display data retrieved from JSON file

I am encountering an unusual issue while trying to retrieve elements from JSON in JavaScript. I fetch a JSON string from a URL using the following code: // Create Request HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"www.someurl ...

Issue encountered when attempting to convert JSON string into a collection

My JSON string looks like this: "{\"Key\":3296,\"Value1\":\"Test1\",\"Value2\":\"City\",\"Value3\":\"TX\",\"Value4\":null,\"Value5\":null,\"Value6\":null}{ ...

Incorporate external JavaScript libraries not built with Angular

Our project utilizes NPM in conjunction with Browserify for managing third-party dependencies, which pairs well with AngularJS due to the CommonJS-modules. Below is a code snippet showcasing the dependency structure that integrates seamlessly with Angular ...

Encountering a syntax error while attempting to import modules from amCharts

Recently, I have been attempting to incorporate amcharts into my project using npm. After running the command npm install@amcharts/amcharts4, I noticed that all the necessary modules were now present in my node_modules folder and package.json file. Specifi ...

Enrollment of Vue components

After importing the component into the JavaScript file, I added it to the index.vue file as follows: import fmsSubUnitDetails from '../subunitDetails'; export default{ components: { fmsSubUnitDetails }, } Despite this, I am still encount ...

What could be causing my AJAX code to fail in retrieving information from an API?

Hey everyone, I'm new here and hoping to get some help with an issue I'm facing. I've written a code to fetch data from an API and display it on my HTML page, but for some reason the AJAX code isn't working. There's nothing showing ...

The default value is not displayed in the Angular dropdown menu

When using regular html select menus, if you create an option element with selected and disabled attributes and provide text for that option, the text will be displayed by default in the select menu. Below is a basic example of HTML code: <select name= ...

What is the best way to ensure the initial item in an accordion group remains open by default when using NextJS?

I've successfully developed an accordion feature in NextJS from scratch and it's functioning flawlessly. However, I am looking to have the first item of the accordion open automatically when the page loads. Can anyone guide me on how to make this ...

JavaScript - Utilizing jQuery to dynamically add and remove input fields

I have a form where input fields (groups) are added dynamically. Here's a glimpse of the complex form: FIDDLE The error on the console reads: Error: uncaught exception: query function not defined for Select2 s2id_autogen1 With existing fields in t ...

Ways to prevent recurring variables in Twitter bootstrap dialogues

I need assistance with deleting multiple links using ajax: <a id="id-1">link1</a> <a id="id-2">link2</a> <a id="id-3">link2</a> <a id="id-4">link2</a> ... This is the simplified version of my code: $(docum ...

The Node module's package.json does not have a main "exports" defined

After recently adding the zx NPM package to my project, I encountered a puzzling issue. The installation went smoothly, and I proceeded to import it into my code: import { $ } from 'zx' (async () => { await $`mkdir test` })() However, u ...

What is the best way to ensure that a task is performed only once the DOM has finished loading following an AJAX request

<div id="mydiv"> ... <a id="my-ajax-link"> ... </a> ... ... <select id="my-selectmenu"> ... </select> ... </div> Upon clicking the 'my-ajax-link' link, it triggers an AJ ...