Generating a JSON tree hierarchy from an array of nested objects

I have a JSON array of objects that looks like this:

[{
    "vehicleid": 3,
    "name": "Teste2VDD",
    "brand": "Scania",
    "model": "6x2",
    "class": "class1",
    "region": "Curitiba",
    "customer": "Cliente A",
    "customerid": 1
},
{
    "vehicleid": 1,
    "name": "Teste1",
    "brand": "Volkswagen",
    "model": "5x3",
    "class": "class1",
    "region": "Curitiba",
    "customer": "Cliente A",
    "customerid": 1
},
{
    "vehicleid": 2,
    "name": "Teste3VDD",
    "brand": "Volkswagen",
    "model": "6x2",
    "class": "class2",
    "region": "Curitiba",
    "customer": "Cliente A",
    "customerid": 1
},
{
    "vehicleid": 5,
    "name": "Teste4VDD",
    "brand": "Scania",
    "model": "6x4",
    "class": "class2",
    "region": "Curitiba",
    "customer": "Novo",
    "customerid": 2
},
{
    "vehicleid": 6,
    "name": "Teste5VDD",
    "brand": "Scania",
    "model": "5x5",
    "class": "class2",
    "region": "Curitiba",
    "customer": "Novo",
    "customerid": 2
},
{
    "vehicleid": 7,
    "name": "veiculo",
    "brand": "Scania",
    "model": "5x4",
    "class": "class1",
    "region": "Porto Alegre",
    "customer": "Cliente3",
    "customerid": 3
},
{
    "vehicleid": 8,
    "name": "veiculo65",
    "brand": "Volkswagen",
    "model": "5x4",
    "class": "class3",
    "region": "Porto Alegre",
    "customer": "Cliente3",
    "customerid": 3
},
{
    "vehicleid": 11,
    "name": "Veiculo de teste h",
    "brand": "Scania",
    "model": "5x3",
    "class": "class3",
    "region": "Belo Horizonte",
    "customer": "Cliente de teste h",
    "customerid": 10
},
{
    "vehicleid": 13,
    "name": "Nome 3",
    "brand": "Volkswagen",
    "model": "6x3",
    "class": "class3",
    "region": "Belo Horizonte",
    "customer": "Cliente de teste h",
    "customerid": 10
},
{
    "vehicleid": 12,
    "name": "Nome",
    "brand": "Volvo",
    "model": "6x3",
    "class": "class3",
    "region": "Belo Horizonte",
    "customer": "Cliente de teste h",
    "customerid": 10
}]

I am looking to create a tree hierarchy based on certain filter parameters.

The first level will always be the customer, and the last level will always be the vehicle.

For example:

1 - Filtering the tree by Customer would result in the tree being ordered by Customer, with each customer's children representing their associated Vehicles:

[{
    "attr": {
        "type": "customer"
    },
    "text": "Cliente A",
    "children": [
        {
            "id": 1,
            "text": "Teste1",
            "attr": {
                "type": "vehicle",
                "title": "Teste1"
            }
        },
        {
            "id": 2,
            "text": "Teste3VDD",
            "attr": {
                "type": "vehicle",
                "title": "Teste3VDD"
            }
        },
        {
            "id": 3,
            "text": "Teste2VDD",
            "attr": {
                "type": "vehicle",
                "title": "Teste2VDD"
            }
        }
    ]
},
{
    "attr": {
        "type": "customer"
    },
    "text": "Novo",
    "children": [
        {
            "id": 5,
            "text": "Teste4VDD",
            "attr": {
                "type": "vehicle",
                "title": "Teste4VDD"
            }
        },
        {
            "id": 6,
            "text": "Teste5VDD",
            "attr": {
                "type": "vehicle",
                "title": "Teste5VDD"
            }
        }
    ]
},
{
    "attr": {
        "type": "customer"
    },
    "text": "Cliente3",
    "children": [
        {
            "id": 7,
            "text": "veiculo",
            "attr": {
                "type": "vehicle",
                "title": "veiculo"
            }
        },
        {
            "id": 8,
            "text": "veiculo65",
            "attr": {
                "type": "vehicle",
                "title": "veiculo65"
            }
        }
    ]
},
{
    "attr": {
        "type": "customer"
    },
    "text": "Cliente",
    "children": [
        {
            "id": 11,
            "text": "Veiculo de teste h",
            "attr": {
                "type": "vehicle",
                "title": "Veiculo de teste h"
            }
        },
        {
            "id": 12,
            "text": "Nome",
            "attr": {
                "type": "vehicle",
                "title": "Nome"
            }
        },
        {
            "id": 13,
            "text": "Nome 3",
            "attr": {
                "type": "vehicle",
                "title": "Nome 3"
            }
        }
    ]
}]

2 - Filtering the tree by Brand would result in the tree being ordered by Customer, with each customer's children representing their associated Brands, followed by the Vehicles under each Brand.

3 - Filtering the tree by both Brand and Model would lead to the tree being ordered by Customer, with each customer's branches showing the respective Brands they own, then the Models under those Brands, and finally the Vehicles for each Model.

4 - If filtering by Brand, Model, and Region", the hierarchy would start at Customer, then show the Brands they are associated with, followed by Models, Regions, and finally Vehicles.

This pattern continues based on different combinations of filters chosen.

If anyone has an idea or solution for implementing this, I would greatly appreciate it!

Thank you in advance!

Answer №1

A unique approach involves utilizing a dynamic strategy by grouping based on specified keys or an object containing group names and keys, then constructing a nested structure using a hash table for each level.

function customGroupBy(arr, keys) {
    var result = [],
        temp = { _: result };

    data.forEach(function (a) {
        keys.reduce(function (r, k, i, kk) {
            var type = typeof k === 'object' ? Object.keys(k)[0] : k,
                key = typeof k === 'object' ? a[k[type]] : a[k];

            if (!r[key]) {
                r[key] = { _: [] };
                r._.push(i + 1 < kk.length
                    ? { attr: { type: type }, text: key, children: r[key]._ }
                    : { id: a.vehicleid, text: key, attr: { type: type, title: key } }
                );
            }
            return r[key];
        }, temp);
    });

    return result;
}

var data = [{ vehicleid: 3, name: "Teste2VDD", brand: "Scania", model: "6x2", class: "class1", region: "Curitiba", customer: "Cliente A", customerid: 1 }, { vehicleid: 1, name: "Teste1", brand: "Volkswagen", model: "5x3", class: "class1", region: "Curitiba", customer: "Cliente A", customerid: 1 }, { vehicleid: 2, name: "Teste3VDD", brand: "Volkswagen", model: "6x2", class: "class2", region: "Curitiba", customer: "Cliente A", customerid: 1 }, { vehicleid: 5, name: "Teste4VDD", brand: "Scania", model: "6x4", class: "class2", region: "Curitiba", customer: "Novo", customerid: 2 }, { vehicleid: 6, name: "Teste5VDD", brand: "Scania", model: "5x5", class: "class2", region: "Curitiba", customer: "Novo", customerid: 2 }, { vehicleid: 7, name: "veiculo", brand: "Scania", model: "5x4", class: "class1", region: "Porto Alegre", customer: "Cliente3", customerid: 3 }, { vehicleid: 8, name: "veiculo65", brand: "Volkswagen", model: "5x4", class: "class3", region: "Porto Alegre", customer: "Cliente3", customerid: 3 }, { vehicleid: 11, name: "Veiculo de teste h", brand: "Scania", model: "5x3", class: "class3", region: "Belo Horizonte", customer: "Cliente de teste h", customeri...
console.log(customGroupBy(data, ['customer', { vehicle: 'name' }]));
console.log(customGroupBy(data, ['brand', 'customer', { vehicle: 'name' }]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

In React js, automatically insert a new row into a table once the Dialog window has

I am currently exploring Reactjs and using Material UI Dialog to implement a dialog box for users to input information and interact with a POST API. After the process is completed, the dialog closes but I would like to dynamically display the added informa ...

Utilize Google Tag Manager to Safely Gather Specific Data

My current project involves capturing values from a <select> element, sending them to the Data Layer, and then forwarding them to an Analytics account via Google Tag Manager. The source code I'm trying to extract values from includes a dynamic s ...

lint-staged executes various commands based on the specific folder

Within my project folder, I have organized the structure with two subfolders: frontend and backend to contain their respective codebases. Here is how the root folder is set up: - backend - package.json - other backend code files - frontend - p ...

Creating a PHP table using JSON data without specifying column names in the array

I am struggling with the Yandex API, trying to retrieve data and create a table using PHP: {"data":[ {"dimensions":[{"name":"organic"}],"metrics":[s1v1,s1v2,s1v3,s1v4,s1v5,s1v6]}, {"dimensions":[{"name":"referral"}],"metrics":[s2v1,s2v2,s2v3,s2v4,s2v5,s2v ...

Using the Angular translate filter within a ternary operator

I am currently working on translating my project into a different language. To do this, I have implemented the Angular Translate library and uploaded an external JSON file containing all the translations. Here is an example of how it looks: { "hello_wor ...

Mobile devices do not support internal link scrolling in Material UI

Currently, I'm utilizing internal links like /lessons/lesson-slug#heading-slug for smooth scrolling within a page. While everything functions perfectly on desktop, it ceases to work on mobile view due to an overlaid drawer nav component. Take a look a ...

Ways to correlate a JSON response value with a Postman environment variable?

When using Postman to set an environment variable, such as 'year', I want to verify if the value of a specific JSON field ('birthYear') matches this variable. My attempt at testing this is as follows: var jsonData = JSON.parse(respons ...

Guide to setting up jQuery Mobile with bower

For my project, I'm interested in utilizing jquery-mobile through bower. In order to do so, I need to execute npm install and grunt consecutively within the bower_components/jquery-mobile directory to access the minified .js and .css files. This pro ...

Display everything when an option is clicked

I have a filter that is working perfectly. When I select a specific category, it filters out only rows with that category. However, I am stuck on how to display all rows again after clicking on the first option. My objective is to show all rows when "Categ ...

The issue with jquery slideToggle is that it mistakenly opens all divs instead of just the specific div that should

My website has a dynamic page with a variable number of <div> elements. The concept is that users can click on the + symbol, which is represented by an <img> tag, to display the corresponding div. Currently, my code includes: PHP/HTML $plus ...

What is the best way to send nested model objects to the parent widget in Flutter?

While attempting to populate my different models with values, I encountered an issue when using the toJson() function of the parent model. This function is supposed to call other models with their objects and create a JSON format that can be sent to Fireba ...

Attempting to construct an 'or' query that relies on the combination of two distinct joined tables

Currently, I am facing a challenge with selecting rows from a PostgreSQL database through Sequelize. I need to retrieve data where the ID exists in either joined table 1 or joined table 2. In my attempts using Sequelize, I used 'include' to quer ...

Hide the dropdown menu when the user clicks anywhere else on the screen

I have a scenario with 2 dropdown buttons. When I click outside the dropdown or on it, it closes. However, if I click on the other dropdown button, it does not close and the other one opens. I want them to close when I click on the other button or anywhere ...

I am looking to transform intricate json data into csv format with the help of either python or R programming

Converting values to rows in CSV and keys to columns in CSV format would be beneficial. { "_id": { "$uId”: “12345678” }, “comopany_productId”: “J00354”, “`company_product name`”: “BIKE 12345”, "search_resu ...

Making a JavaScript script compatible with select drop down menus that can handle multiple selections

After searching through various sources, I came across two threads that address my question regarding the code to use. Despite finding solutions, I am struggling to understand how to implement the script. My limited experience with JavaScript is likely cau ...

Encoding a string in JSON that contains the "#" symbol along with other special characters

The client side javascript code I have is as follows: <html> <script type="text/javascript" src="js/jquery.min.js"></script> <script> $(document).ready(function() { //var parameters = "a=" + JSON.stringify( ...

Ways to show text on a donut chart when hovering with the mouse

I have been attempting to make adjustments to this sample. My goal is to display a word in the center of the donut chart upon mouseover, similar to this: https://i.sstatic.net/dCPKP.png Although I have included code for mouseover, it seems to not be func ...

Is there a way to create an infinite fade in/out effect for this?

Is there a way to ensure that the method runs after the "click" event in this code snippet? The code currently fades in and out the div #shape while the start variable is true, but when I call the "start" method from the "click" event, the browser stops wo ...

Angular log out function to automatically close pop-up windows

Within my application, there is a page where users can open a popup window. When the user clicks on logout, it should close the popup window. To achieve this, I have used a static variable to store the popup window reference in the Global.ts class. public ...

Initiate monitoring for child component modifications

I'm looking to disable 'changeDetection' for the parent component while enabling it for the child component. Can you provide an example of how this can be achieved? The parent component contains static data, meaning change detection is not ...