Descending through layers of a flattened array of objects

I've been diving into the world of array of objects and have successfully flattened them. Now I'm faced with the challenge of nesting them based on unique values at different levels. Currently, I'm using the reduce method to achieve this, but I end up getting new objects for each entry.

data = [
{ name1 : 'Tennis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Singles', id3: 4},
{ name1 : 'Tennis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Singles', id3: 4},
{ name1 : 'Tennis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Doubles', id3: 5},
{ name1 : 'Tennis', id1: 1, name2: 'WTA', id2: 3, name3: 'Women Doubles', id3: 6},
{ name1 : 'Tennis', id1: 1, name2: 'WTA', id2: 3, name3: 'Women Singles', id3: 7}
]

Desired result:

result: [
 { sport: 'Tennis', 
   league: 
      [{ 
       ATP: [{ event: 'Men Singles', 'Men Doubles' }],
       WTA: [{ event: 'Women Singles', 'Women Doubles' }]
      }]
}]

Current code snippet:

const result = data.reduce((arr, item) => {
        if (arr.indexOf(item.name1) === -1) {
          arr.push({
            sport: item.name1 ,
            league: item.name2 ,
            event: item.name3
          })
        }
        return arr;
      }, [])

The issue is that I'm getting every value individually like so:

0: {sportName: 'Tennis', league: 'ATP', event: 'Men Singles'}
1: {sportName: 'Tennis', league: 'WTA', event: 'Women Doubles'}
2: {sportName: 'Tennis', league: 'WTA', event: 'Women Doubles'}
.... etc

How can I modify my approach to obtain a single nested object as desired? I'm feeling quite stuck at the moment.

Answer №1

If you want to optimize your code, avoid wrapping each object with an array

const data = [{ name1 : 'Tenis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Singles', id3: 4},{ name1 : 'Tenis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Singles', id3: 4},{ name1 : 'Tenis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Doubles', id3: 5},{ name1 : 'Tenis', id1: 1, name2: 'WTA', id2: 3, name3: 'Women Doubles', id3: 6},{ name1 : 'Tenis', id1: 1, name2: 'WTA', id2: 3, name3: 'Women Singles', id3: 7}]

const tranform = () => {
  const sport = data[0]['name1'];
  const league = data.reduce((r, e) => {
      r[e['name2']] ??= []
      if (!r[e['name2']].includes(e['name3'])) {                
        r[e['name2']].push(e['name3'])
      }
      return r;
  }, {});

  return { sport, league };
};
  
console.log(tranform())
.as-console-wrapper { max-height: 100% !important; top: 0 }

Answer №2

To ensure that the value is not already present in specific inner arrays, you must push it. This process is executed for sport, followed by league, and finally the event.

It's worth noting that I utilized an array for the events property.

data = [
{ name1 : 'Tennis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Singles', id3: 4},
{ name1 : 'Tennis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Singles', id3: 4},
{ name1 : 'Tennis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Doubles', id3: 5},
{ name1 : 'Tennis', id1: 1, name2: 'WTA', id2: 3, name3: 'Women Doubles', id3: 6},
{ name1 : 'Tennis', id1: 1, name2: 'WTA', id2: 3, name3: 'Women Singles', id3: 7}
]


const result = data.reduce((output, obj) => {
  // Check on Sport - if not found, include the sport with its corresponding league & event
  const sportObj = output.find(item => item.sport === obj.name1)
  if (!sportObj) {
    output.push( 
      { 
        sport: obj.name1,
        league: [{
          [obj.name2]: [{ events: [obj.name3] }]
         }] 
       })
    return output
  }
  // Check on League - If not present, add a league to the sport with the current event
  const leagueObj = sportObj.league[0][obj.name2]
  if (!leagueObj) {
    sportObj.league[0][obj.name2] = [{ events: [obj.name3] }]
  } else {
    // Event Check - if not in, add the event. Otherwise, no action needed.
    const eventsArray = leagueObj[0].events
    if (!eventsArray.includes(obj.name3)) eventsArray.push(obj.name3)
  }
  return output
}, [])
 
 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

Troubleshooting problem with the Node and Mongoose update function

I am looking to update a document that has already been queried: The method of saving in memory seems to be working well: project.likers.push(profile.id); project.set({ likes: project.likes + 1 }) await project.save(); However, I came across a blog p ...

When selecting an old list, only the most recently created ID is displayed, rather than the ID of the specific list being

I've set up a dashboard where I can create lists and have them displayed on the screen, but there seems to be an issue when trying to open any list as only the last created one opens. Can anyone point out what mistake I might be making? The technologi ...

Problem with jQuery: Modifications to CSS made before an each loop are only applied afterwards

Below is some code I am working with: LoadingImage.show("#contentpage", urlStk.LoadImg); var errors = 0; var ComponentToUpdate = new Array(); var storedItems = JSON.parse(localStorage.getItem("Components")); $(".myDataGridRow").each(function () { er ...

Ways to have a list component smoothly descend when a dropdown menu is activated

I have a situation where I have a list with two buttons, and each button triggers the same dropdown content in a sidebar component. The issue is that when I click on one button to open the dropdown, the second button does not move down to make space for it ...

Get canvas picture through JS Jquery

I've been attempting to save a canvas image to my desktop using this code: <script type="text/javascript"> var canvas; $(document).ready(function() { if ($('#designs-wrapper').length) { $('.design').eac ...

The Bootstrap modals seem to be invisible within the Rails application

Currently, I am integrating jquery into the devise views of a sample rails application. My intention is to test it on a sample app before implementing it in a production code. The controller and view for welcome are already set up. The routes.rb file loo ...

Removing an embedded document from an array in MongoDB using Mongoose when the document's status is set to false

I am in desperate need of a solution for this mongoose-related issue. My tech stack includes Express, Mongoose, and GraphQL. To give you some context, I have two collections: users and groups. user { name: string, groupAsMember: [groups], status: bo ...

Tips for maintaining an active class on parent nav items in NextJS when navigating dynamic routes

In my nextjs-application, I've implemented a Navbar showcasing several navitems: Navbar.tsx: const Navbar = ({ navitems }) => { return ( <div> {navitems?.map((navitem, idx) => ( <NavItem key={idx} navitem={nav ...

Activate event in jQuery when clicking on a blank area, away from any div element

I need help figuring out how to hide a div when empty space on the margins of the page is clicked, as opposed to just any area outside of the div. I've managed to achieve this functionality when certain other divs are clicked, but I'm stuck on im ...

Exploring the use of arrays in Vue JS

Currently, I am working on a small project using VueJS 2.0, and it involves handling data that looks like this: {"data": [ { "id":8, "salutation":"Mr", "first_name":"Madhu", "last_name":"Kela", ...

Adding items to a JSON document

My task involves creating a pseudo cart page where clicking on checkout triggers a request to a JSON file named "ordersTest.json" with the structure: { "orders": [] }. The goal is to add the data from the post request into the orders array within the JSO ...

Is it possible to automatically set focus on the input box in an html tag multiple times instead of just once with autofocus?

Currently, I am developing an online editor that allows users to quickly edit individual words. My approach involves replacing specific words with input boxes containing the word for direct editing by users. In order to streamline the process and ensure e ...

Vue.js does not support the usage of external JSON files directly within HTML documents

I'm encountering issues fetching data from an external JSON file for a specific variable. I suspect that the problem lies in using Vue.js within the HTML, as it seems to be having trouble interpreting my code correctly.:joy: jsfiddle Additionally, I ...

NodeJS npm module installed globally is unable to run the main/bin JavaScript file using node command

Here is an example of my package.json: { "name": "example-module", "version": "1.0.0", "bin": "./bin/example-module.js", "main": "./bin/example-module.js", "description": "Example module description", "homepage": "http://my.home.page.com", " ...

Crafting 3 intertwined combinations using the power of jQuery AJAX and PHP

Here's what I've been working on so far: The first page retrieves data and populates the first combobox, which is all good. Then, when users select a value from combo1, a second combobox is created with filtered data using AJAX - also working fin ...

Is it possible to use a shell script to replace the external CSS file link in an HTML file with the actual content of the CSS file

Seeking a solution for replacing external CSS and JS file links in an HTML document with the actual content of these files. The current structure of the HTML file is as follows: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C ...

Express route not capturing entire request parameter due to regex issue

I am pretty sure that the issue lies in how express handles regex patterns in route definitions, although it might also be related to my pattern (I'm still new to regex, so please bear with me). In my express route definition, I am attempting to match ...

What is the most effective approach for annotating TypeScript abstract classes that are dynamically loaded?

I am in the process of developing a library that allows for the integration of external implementations, and I am exploring the optimal approach to defining types for these implementations. Illustration abstract class Creature { public abstract makeN ...

Modifying the value property of the parent element

Here is an example of the HTML code I am working with: <td value='3' style='text-align: center'> <select class='selection' onchange=''> <option value='1'>1</option> <opti ...

The importance of adding ".$" to an AngularJS filter object

I have been exploring a section of code related to filtering in AngularJS from the documentation website. (cf. http://docs.angularjs.org/api/ng.filter:filter) Specifically, I am curious about the use of .$ appended to the object search, as shown in the fo ...