Convert data into a tree view in JavaScript, with two levels of nesting and the lowest level represented as an array

Here is an example of a JSON object:

[
  {
    "venueId": "10001",
    "items": [
      {
        "venueId": "10001",
        "locationId": "14",
        "itemCode": "1604",
        "itemDescription": "Chef Instruction",
        "categoryCode": "28",
        "categoryDescription": "Food Instructions",
        "qty": 0,
        "saleValue": 0,
        "saleDatetime": "0001-01-01T00:00:00",
        "timeToLive": 0
      },
      ... (more item details)
    ]
  }
]

I am looking to rearrange this data into a new JSON object where it is grouped by id and then by category code. The desired format is like the following structure:

{
    '1': { 
        '555': [{ itemCode: '456'}, { itemCode: '457'}, { itemCode: '458'}]
    }
}

Is there a straightforward method to achieve this using lodash, plain JavaScript, or any available NPM package? This task is similar to another query found here: JavaScript group data into tree view 2 levels deep but with the distinction that the third level involves an array of objects.

Answer №1

To group the data, you can utilize two nested loops to create new objects or arrays as needed.

var data = [{ venueId: "10001", items: [{ venueId: "10001", locationId: "14", itemCode: "1604", itemDescription: "Chef Instruction", categoryCode: "28", categoryDescription: "Food Instructions", qty: 0, saleValue: 0, saleDatetime: "0001-01-01T00:00:00", timeToLive: 0 }, { venueId: "10001", locationId: "14", itemCode: "1381", itemDescription: "Meat Lovers Pizza", categoryCode: "48", categoryDescription: "25Fore - Pizza", qty: 0, saleValue: 0, saleDatetime: "0001-01-01T00:00:00", timeToLive: 0 }, { venueId: "10001", locationId: "14", itemCode: ...

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

Answer №2

In my opinion, the most efficient approach would involve utilizing a simple double loop method. First, iterate over each row and then within that, iterate over the individual items. By doing this, you can easily populate the final object with the desired structure:

var initialArray = [
    {
        id: '1', 
        items: [
            {
                id: '1',
                saleId: '123',
                saleIdAndItemId: '123456',
                locationId: '123',
                itemCode: '456',
                itemDescription: 'my item',
                categoryCode: '555',
                categoryDescription: 'my category',
                qty: 10,
                saleValue: 200
            },
            {
                id: '1',
                saleId: '123',
                saleIdAndItemId: '123456',
                locationId: '123',
                itemCode: '457',
                itemDescription: 'my item',
                categoryCode: '555',
                categoryDescription: 'my category',
                qty: 10,
                saleValue: 200
            },
            {
                id: '1',
                saleId: '123',
                saleIdAndItemId: '123456',
                locationId: '123',
                itemCode: '458',
                itemDescription: 'my item',
                categoryCode: '555',
                categoryDescription: 'my category',
                qty: 10,
                saleValue: 200
            }
        ]
    },
    {
        id: '2', 
        items: [
            {
                id: '2',
                saleId: '123',
                saleIdAndItemId: '123456',
                locationId: '123',
                itemCode: '456',
                itemDescription: 'my item',
                categoryCode: '556',
                categoryDescription: 'my category 6',
                qty: 10,
                saleValue: 200
            }
        ]
    },
    {
        id: '3', 
        items: [
            {
                venueId: '3',
                saleId: '123',
                saleIdAndItemId: '123456',
                locationId: '123',
                itemCode: '457',
                itemDescription: 'my item',
                categoryCode: '557',
                categoryDescription: 'my category 7',
                qty: 10,
                saleValue: 200
            }
        ]
    }
];

var finalObject = {},
    currentRow = {},
    currentItem = {},
    newItemObject = {};

for (var i in initialArray) {
    currentRow = initialArray[i];
    newItemObject = {};
    for (var j in currentRow.items) {
        currentItem = currentRow.items[j];
        // Check if the category code already exists in the newItemObject
        if (!newItemObject.hasOwnProperty(currentItem.categoryCode)) {
            newItemObject[currentItem.categoryCode] = [];
        }
        // You can choose to push the entire currentItem or just specific data
        // newItemObject[currentItem.categoryCode].push(currentItem);
        newItemObject[currentItem.categoryCode].push({
            'itemCode': currentItem.itemCode
        });
    }
    
    finalObject[currentRow.id] = newItemObject;
}

console.log(finalObject);

Answer №3

Upon reviewing your linked question, it appears that you are seeking additional properties beyond those listed in the provided example. Below is a function designed to convert your data into the specified format, with the flexibility to specify which nested keys should be included in the output:

const transformData = (array, keysToInclude) => {
  const result = {};
  for (const group of array) {
    const id = {};
    result[group.venueId] = id;
    for (const item of group.items) {
      let category = id[item.categoryCode];
      if (!category) {
        category = [];
        id[item.categoryCode] = category;
      }
      if (!keysToInclude) {
        category.push(item);
        continue;
      }
      const itemData = {};
      for (const key of keysToInclude) {
        if (Object.keys(item).includes(key)) itemData[key] = item[key];
      }
      category.push(itemData);
    }
  }
  return result;
};

const data=[{venueId:"10001",items:[{venueId:"10001",locationId:"14",itemCode:"1604",itemDescription:"Chef Instruction",categoryCode:"28",categoryDescription:"Food Instructions",qty:0,saleValue:0,saleDatetime:"0001-01-01T00:00:00",timeToLive:0},{venueId:"10001",locationId:"14",itemCode:"1381",itemDescription:"Meat Lovers Pizza",categoryCode:...

const onlyItemCodes = transformData(data, ['itemCode']);
const allKeys = transformData(data);

const log = data => console.log(JSON.stringify(data, null, 2));

log(onlyItemCodes);
log(allKeys);

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 performance of the Ionic app is significantly hindered by lagging issues both on Google

After starting to work with the ionic framework, I noticed a significant change in performance when testing an android app on Chrome for the first time. It was fast and responsive until I added a button that led to a screen with navigation bars, side men ...

position text to the right side of a slider gallery created with JavaScript

I'm currently utilizing a WordPress plugin known as Slideshow Gallery and I want to position the text below it to float next to the gallery on the right side. I've attempted the following: .bioText{ font-size: 14px; font-size: 1.428571429rem; ...

Using the MongoDB aggregate framework to determine the total employee count per unique state

I'm currently working on displaying the total number of employees for each state within companies located in the USA. I aim to showcase this information for all states included in the dataset using sample numbers as a reference: AZ : 1234 CA : 30000 ...

Unveiling the secrets of the Google Region Lookup API

I am struggling to incorporate the Region Area Lookup feature from Google Maps into my project. Despite it being an experimental feature, I am having difficulty getting it to function correctly. Initially, I attempted to integrate this feature into a Reac ...

Converting string patterns to regular expressions

I am utilizing mongodb to store data. My requirement is to save complete regular expressions as strings: { permissions: [{ resName: '/user[1-5]/ig', isRegex: true }] } Although I am aware of the existence of the module mongoose-rege ...

Accessing and fetching data from a PostgreSQL database using JavaScript through an API

I am currently working with an npm package called tcmb-doviz-kuru to fetch currency data from an API and then insert it into my database. However, I am facing an issue with mapping the data to properly insert the values. Below is my code snippet: var tcmbD ...

Locate and embed within a sophisticated JSON structure

I have an object structured as follows: interface Employee { id: number; name: string; parentid: number; level: string; children?: Employee[]; } const Data: Employee[] = [ { id:1, name: 'name1', parentid:0, level: 'L1', children: [ ...

Does the webworker function as a multi-thread?

For example: worker.postMessage(data1); worker.postMessage(data2); If there are multiple issues to be dealt with inside the web worker, would worker.postMessage(data2) block before completing data1? ...

Substitute the website address using regular expressions

Looking to update the iframe URL by changing autoplay=1 to autoplay=0 using regular expressions. jQuery(document).ready(function($){ $('.playButton').click(function(){ $('.flex-active-slide iframe').contents().f ...

Ways to reveal concealed div elements when hovering the mouse?

Is there a way to display a group of hidden div's when hovering over them? For instance: <div id="div1">Div 1 Content</div> <div id="div2">Div 2 Content</div> <div id="div3">Div 3 Content</div> All div's sho ...

Out of nowhere, JavaScript/jQuery ceased to function

Everything was running smoothly on my website with jQuery Ui until I changed the color, and suddenly everything stopped working. Any ideas why this happened? I even tried writing the JavaScript within the HTML file and linking it as a separate .js file, bu ...

Nodejs - Utilizing Express and Mongoose to Implement URL Routing by Name

My Express 4 server has CRUD routes specifically for authors: router.get('/authors', AuthorsController.index); router.post('/authors', AuthorsController.store); router.get('/authors/:name', AuthorsController.show) ...

Guide on Retrieving the Current URL in NodeJS

Currently, I am utilizing express in conjunction with node.js. In my setup, the following code is present: app.get('/callback', async function (req, res) { Whenever a user reaches the callback section of my website, I expect to receive the req ...

The Javascript function is malfunctioning, unable to assign the 'onclick' property to null

Here's the code snippet I'm working with: var exit = document.getElementById("exit"); exit.onclick = function() { "use strict"; document.getElementById("fadedDiv").style.display = "none" ; }; However, when I check the console, it shows ...

"Unable to move past the initial segment due to an ongoing

My portfolio webpage includes a "blob" and "blur" effect inspired by this YouTube video (https://www.youtube.com/watch?v=kySGqoU7X-s&t=46s). However, I am encountering an issue where the effect is only displayed in the first section of the page. Even a ...

When the page initially loads, the block appears on top of the upper block and remains in place after the page is refreshed

Upon initial loading, the block appears on top of another block but remains fixed upon page refresh. The same issue occurs in the mobile version of the site and occasionally displays correctly. The website is built on WordPress and optimized using Page Spe ...

What causes the disparity in functionality between simple html and css in an Angular 2 project compared to a vanilla html website?

When incorporating the following html/css into a new Angular project created with Angular CLI using 'ng new ProjectName', I encountered issues. Despite adding the CSS to app.component.css or styles.css and the HTML to app.component.html, the Angu ...

Trouble arises when trying to combine NextJs 12.2.5 with next-auth 4.17 due to a dependency

npm ERROR! Could not find a solution for the dependency: npm ERROR! required peer next@"^12.2.5 || ^13" by [email protected] npm ERROR! in node_modules/next-auth npm ERROR! next-auth version is "*" as defined in the root project ...

Calling Ajax in JavaScript

Trying to fetch a value in JavaScript using an Ajax Call, The code being used is as follows: <script> var value = $.ajax({ type:"GET", url:"get_result.php", data:"{'abc':" + $abc + "}", }); alert(val ...

Parent Directory Injector: Prioritizing Injection of Parent Directories

Currently, I am utilizing 'grunt-injector' to inject a list of files using 'app/**/*.js'. However, I am facing dependency errors due to the alphabetical order in which the files are injected. To avoid these issues, I am looking for a so ...