JavaScript can intelligently extract and categorize an array of objects based on their properties

In essence, I aim to develop a versatile function "organize" that can transform the following data structure:

[
    { name: 'band1', type: 'concert', subtype: 'rock' },
    { name: 'band2', type: 'concert', subtype: 'jazz' },
    { name: 'band3', type: 'concert', subtype: 'jazz' },
    { name: 'fun1', type: 'festival', subtype: 'beer' },
    { name: 'fun2', type: 'festival', subtype: 'food' },
]

into this organized format:

{
    'concert': {
      'rock': [
        { name: 'band1', type: 'concert', subtype: 'rock' },
      ],
      'jazz': [
        { name: 'band2', type: 'concert', subtype: 'jazz' },
        { name: 'band3', type: 'concert', subtype: 'jazz' }
      ]
    },
    'festival': {
      'beer': [
        { name: 'fun1', type: 'festival', subtype: 'beer' },
      ],
      'food': [
        { name: 'fun2', type: 'festival', subtype: 'food' },
      ]
    }
}

based on the parameters provided in the method call:

organize(events, ['type', 'subtype']);

The main goal behind this restructuring is to simplify the process of iterating over and displaying the data. In Vue.js terms, the output would resemble something like this:

<div v-for="(type, subtypes) in organize(events, ['type', 'subtype'])">
  <h1>{{ type }}</h1>
  <div v-for="(subtype, events) in subtypes">
    <h2>{{ subtype }}</h2>
    <div v-for="event in events">
      <h3>{{ event.name }}</h3>
    </div>
  </div>
</div>

This implementation has been quite challenging for me, as I believe it could involve recursion and potentially a combination of methods like map, filter, and reduce. However, my attempts so far have resulted in rather convoluted code that achieves similar functionality. It's also plausible that there are features in JavaScript that I am not utilizing efficiently for this task.

I welcome any advice or direction on this matter, though it's not an urgent issue. I simply see great value in having a universal function for organizing arrays in this manner.

Answer №1

After analyzing the code snippet, I believe this implementation of the organize function is accurate:

function organize(rows, groupBy) {
    var last = groupBy.length - 1;
    return rows.reduce ( (res, obj) => {
        groupBy.reduce( (res, grp, i) => 
            res[obj[grp]] || (res[obj[grp]] = i == last ? [] : {}), res).push(obj);
        return res;
    }, {});
}

var events = [
    { name: 'band1', type: 'concert', subtype: 'rock' },
    { name: 'band2', type: 'concert', subtype: 'jazz' },
    { name: 'band3', type: 'concert', subtype: 'jazz' },
    { name: 'fun1', type: 'festival', subtype: 'beer' },
    { name: 'fun2', type: 'festival', subtype: 'food' },
];

var result = organize(events, ['type','subtype']);

console.log(result);

Answer №2

If you want to categorize and group data in JavaScript, you can make use of the _.groupBy() function provided by the LoDash library:

var data = [
  { name: 'band1', type: 'concert', subtype: 'rock' },
  { name: 'band2', type: 'concert', subtype: 'jazz' },
  { name: 'band3', type: 'concert', subtype: 'jazz' },
  { name: 'fun1', type: 'festival', subtype: 'beer' },
  { name: 'fun2', type: 'festival', subtype: 'food' },
];
  
var groupedByType = _.groupBy(data, 'type');
console.log(groupedByType);
  
var groupedByTypeAndSubtype = {};
for (var key in groupedByType) {
  groupedByTypeAndSubtype[key] = _.groupBy(groupedByType[key], 'subtype');
}

console.log(groupedByTypeAndSubtype);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.2/lodash.js"></script>

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 Express.js server seems to be having trouble rendering a static JavaScript file

Currently, I am in the process of constructing a website and have implemented an express.js server to collect data submitted through a form. Prior to configuring the server, I had already developed the site using static js and css files. Once the connectio ...

Is there a concept in JavaScript that includes a data structure called a "matrix" with elements arranged in a grid-like format accessed by

I'm not familiar with the terminology, but I'd like to simplify it: var topicList1 =['hello','hallo', ..., 'hej']; var topicList2 =['a','b',...,'c']; ... var topicList999 =['x,&apo ...

Having issues with creating a poll command for my Discord bot as it keeps throwing the error message: "Oops! TypeError: Cannot read property 'push' of undefined."

Can anyone assist me with my question? I am using discord v11.5.1 Below is the code: exports.run = async (bot, message) => { const options = [" ...

Redirecting the socket.io client to the Heroku service

Recently, I developed a real-time chat application using socket.io, Node.JS, and express. It was functional on my local server but now I want to connect it to an existing Heroku service instead. How can I achieve this? Once I tried the following code, va ...

Unable to retrieve function variables stored in fancytree source nodes within its activate method

If the configuration of my fancytree includes a source like this: source: [{ title: "Item1", key: "1", myFunc: function (item) { return 'function'; ...

What is the best way to ensure that the same information is included on every page of

Currently developing a dynamic website where certain components such as the fixed header, menubar, and footer are common across multiple pages. What is the best way to include these fixed components on every webpage? I am utilizing JSP and JavaScript for ...

Trigger a keyframe animation upon initial click and then reverse playback on the subsequent click

I'm struggling to create a wave animation that fills the screen up to a certain point and stops on the first click of a navigation menu. I've attempted to have it play in reverse when the navigation menu is clicked again, but it's not workin ...

What is the best way to incorporate a <c:forEach> loop into JSP operations?

I am attempting to calculate the product of two variables that are associated with an item in a loop. Below is the code snippet from the JSP file: <table> <thead> <tr> <th>PRICE</th> <th ...

Steps for generating tab panels and their respective content using a v-for loop

I am currently utilizing Vue 3 in combination with Bootstrap 5. My objective is to incorporate multiple Tabpanels within a v-for. Each of these Tabs should feature distinct content. To achieve this, I attempted placing my Tabs and their respective Conten ...

Is it possible for me to reconstruct the "reducer" each time the useReducer hook is rendered?

Here is an example taken from: https://reactjs.org/docs/hooks-reference.html#usereducer const initialState = {count: 0}; function reducer(state, action) { switch (action.type) { case 'increment': return {count: state.count + 1}; ...

Transferring Variables from WordPress PHP to JavaScript

I have implemented two WordPress plugins - Snippets for PHP code insertion and Scripts n Styles for JavaScript. My objective is to automatically populate a form with the email address of a logged-in user. Here is the PHP snippet used in Snippets: <?p ...

How can I adjust the position of a target point in the chase camera using THREE.js?

Recently, I've delved into the world of THREE.js and decided to create a game featuring a spaceship as the main element. Utilizing a chase camera for my model, I encountered a challenge where I needed to adjust the camera's position in relation t ...

Guide on adding checkboxes for each child component in a Vue ads table

<vue-ads-table :columns="fields" :rows="items" :selectable="true" @row-selected="onRowSelected" class="my-table" ...

How to redirect in Next.js from uppercase to lowercase url

I'm trying to redirect visitors from /Contact to /contact. However, following the instructions in the documentation results in an endless loop of redirects. This is my attempted solution: // next.config.js async redirects() { return [ { ...

Closing a Javascript Websocket connection may result in server crash

I encountered an issue while trying to exchange data between my client and server. It seems that every time I closed my client, the server crashed... My server runs on Node.JS using the nodejs-websocket library. After some investigation, I discovered tha ...

In the React js and emotion framework, fonts are only loaded in production mode after the page has been re

I have set up emotion's Global component to globally apply a font to my app: export const GlobalStyle: FC<{}> = () => ( <Global styles={css` @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@100;300;400;50 ...

Blocking the space bar in JavaScript is a useful technique that can be

I'm in the process of developing an application and I'm looking to prevent the space bar from scrolling my page My framework of choice is VUE, and I am trying to trigger a method using an event handler However, when I attempt to call the ' ...

Rotation of objects using Three.js on a spherical surface

I have successfully implemented a particle system to evenly distribute points on a sphere and then place instances of a given geometry on those points. Now, I am looking to rotate those geometries to match the surface angle of the sphere. Below is the cur ...

Obtaining the Span value inside a DIV when the text in the DIV is selected - JavaScript

I am dealing with a series of div elements structured in the following way: <div id="main1"> <span class="username">Username_1</span> white some text content inside div... blue some text content inside div... yellow some ...

Using Vue: Triggering .focus() on a button click

My journey with vue.js programming started just yesterday, and I'm facing a challenge in setting the focus on a textbox without using the conventional JavaScript method of document.getElementById('myTextBox').focus(). The scenario is that i ...