Reorganize JSON data in JavaScript

I am in the process of creating a tree structure, and I want it to be organized in the order of name, desc, then children. However, the JSON data I have received is not in this order. Is there a way to rearrange it efficiently or perhaps optimize the code considering multiple branches and potential additional elements being added to the input?

Below is the current code snippet:

var arry = [{   
        "name": "J", 
        "target": "L",
        "desc": "2"
    },

    {
        "name": "L",    
        "target": "A",    
        "desc": "1"    
    },    
    {  
        "name": "S",  
        "target": "L",  
        "desc": "3"  
    }

];

function toJSON(data) {   
    var root = data.find(function(x) {   
        return !data.some(function(y) {  
            return y.name === x.target  
        });
}).target;
    console.log(root)



    var desc = data.find(function(x) {

        return !data.some(function(y) {

            return y.name === x.target

        });

    }).desc;




    var b = data.reduce(function(acc, x) {

        acc[x.target] = acc[x.target] || [];

        acc[x.target].push(x.name);

        return acc;



    }, {});  
    var tree = buildTree(root, b);   
    function buildTree(name, branches, desc) {
        var tree = {
            'name': name
        }; 
        if (branches[name]) {   
            tree.children = branches[name].map(function(x) {
                return buildTree(x, branches, desc)
            });
            for (var child in branches[name]) {
                var x = arry.find(function(i) {
                    return (i.name === branches[name][child] && i.target === name)    
                })    
                tree.children[child].desc = x.desc    
            }    
        }
        return tree;
    }
    if (tree.name === root) {    
        tree.desc = root   
    }
    for (var i in tree) {
         console.log(i)  
    }   
    return tree;
} // JavaScript name code  
var a = toJSON(arry)

console.log(JSON.stringify(a, null, 2))

The resulting output obtained is:

{
  "name": "A",
  "children": [
    {
      "name": "L",
      "children": [
        {
          "name": "J",
          "desc": "2"
        },
        {
          "name": "S",
          "desc": "3"
        }
      ],
      "desc": "1"
    }
  ],
  "desc": "A"
} 

The desired result should be:

 {
      "name": "A",
      "desc": "A",
      "children": [
        {
          "name": "L",
          "desc": "1",
          "children": [
            {
              "name": "J",
              "desc": "2"
            },
            {
              "name": "S",
              "desc": "3"
            }
          ]
       }
      ]
    }

Answer №1

I completely agree with the question regarding the importance of order.

However, if you are truly interested in understanding this further...

When it comes to creating object literals, the sequence in which keys/properties are defined is crucial as they will remain in that same order unless the keys are integers. In your code snippet, you first define an object for your tree node with just the 'name' property, then add 'children', and finally set 'desc'. To maintain a specific order, it's more effective to define the object with all properties right from the start. This way, you retain control over the order and can easily manipulate the values later on.

const tree = {
  name,
  desc: undefined,
  children: undefined,
};

https://codesandbox.io/s/dazzling-bell-8l6q2?fontsize=14

var arry = [
  {
    name: "J",
    target: "L",
    desc: "2"
  },

  {
    name: "L",
    target: "A",
    desc: "1"
  },
  {
    name: "S",
    target: "L",
    desc: "3"
  }
];

function convertToJSON(data) {
  var root = data.find(function(x) {
    return !data.some(function(y) {
      return y.name === x.target;
    });
  }).target;

  console.log(root);

  var desc = data.find(function(x) {
    return !data.some(function(y) {
      return y.name === x.target;
    });
  }).desc;

  var b = data.reduce(function(acc, x) {
    acc[x.target] = acc[x.target] || [];
    acc[x.target].push(x.name);
    return acc;
  }, {});

  var treeData = buildTree(root, b);

  function buildTree(name, branches, desc) {
    // specify the structure of your tree node here
    var treeNode = {
      name,
      desc: undefined,
      children: undefined
    };

    if (branches[name]) {
      treeNode.children = branches[name].map(function(x) {
        return buildTree(x, branches, desc);
      });
      
      for (var child in branches[name]) {
        var x = arry.find(function(i) {
          return i.name === branches[name][child] && i.target === name;
        });
        
        treeNode.children[child].desc = x.desc;
      }
    }

    return treeNode;
  }

  if (treeData.name === root) {
    treeData.desc = root;
  }

  for (var i in treeData) {
    console.log(i);
  }

  return treeData;
}

var result = convertToJSON(arry);

console.log(JSON.stringify(result, null, 2));

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

Clicking a button in React requires two clicks to update a boolean state by triggering the onClick event

I have a React functional component with input fields, a button, and a tooltip. The tooltip is initially disabled and should only be enabled and visible when the button is clicked and the input fields contain invalid values. The issue I'm facing is t ...

Exploring the capabilities of Angular and UIGrid for fetching table information

I have been utilizing Angular along with uigrid, which is an excellent library for displaying data in a tabular format. Everything looks good when displaying the table. However, when I update an item and click on a Save button that triggers a rest service ...

Subclass declaration with an assignment - React.Component

I recently started going through a React tutorial on Egghead and came across an interesting class declaration in one of the lessons: class StopWatch extends React.Component { state = {lapse: 0, running: false} render() { const ...

Tips on deleting the last character in an input field with AngularJS

Can you help me with the title of this question? I'm currently working on developing a straightforward calculator using AngularJS. It's operational at the moment, but I'm looking to incorporate additional buttons like a "delete" key and a de ...

Transforming an array into an object is made easy with Laravel's collection

When I use $collection->filter(myFilter) in Laravel, it automatically assigns keys to each model in the collection. This results in output like: { "4": { "myObject": "data" }, "7": { "myObject": "data" } } Is there a wa ...

The Clash of Form Action and JavaScript

Can someone help me with this issue? I have a form and a script to trigger an alert message. The code I'm using is working well: <input id="autocomplete" class="input_message" type="text" name="message" autocomplete="off" placeholder="...typ ...

Tips for displaying a message in the model body when a bootstrap model does not have any data in jQuery

Having trouble displaying a text message in the Bootstrap modal body when there is no data available in the model. I have multiple cards in the model, and if I click on the skip or done buttons, each card will close. However, if there is only one card in t ...

What causes the delay in loading certain CSS and JS files?

My ASP.NET MVC5 application hosted on an IIS Server has a slow-loading login page, especially after clearing the browser history. The Developer Tools Network field indicates a problem with loading page contents such as css and js files. Can you provide gui ...

JavaScript click or text-to-speech

Currently, I am working on a web application that is designed to automatically read text. Below is the code snippet that I am using: function hablalo() { var palabra = new SpeechSynthesisUtterance('Casilla 6 turno E18'); palab ...

Is it possible to test code that utilizes a different framework from jQuery using QUnit?

Currently, I am in the process of developing a compact library that is capable of utilizing multiple frameworks (specifically jQuery, Prototype, YUI2). To ensure its functionality, I am conducting tests using QUnit. Nevertheless, one setback is that QUnit ...

Leverage the controller's properties and methods within the directive

My situation involves a variety of inputs, each with specific directives: <input mask-value="ssn" validate="checkSsn"/> <input mask-value="pin" validate="checkPin"/> These properties are managed in the controller: app.controller("Ctrl", [&ap ...

Can we consider it proper JSON (schema) to specify that an element can either be a singular item or an array?

Is it feasible to define a specific json value that can be either a single element or an array? For example, can both of the following json documents be considered valid based on a single json schema? "person": { "name": "john", "friends": "jack" ...

Utilizing AJAX in Yii2 to fetch data values

I have a field called _form.php <?php $form = ActiveForm::begin(); ?> <?= $form->field($model, 'IdKaryawan')->widget(Select2::classname(), [ 'data' => $listData, 'options' => [&apo ...

When the user modifies the input, React fails to update the component state

Currently, I am utilizing React in conjunction with express to server-side render the views for my project. However, I have encountered a minor setback. Within one of my components, users are directed after their initial login. Here, they are prompted to ...

Make a call to a remote node.js server using an ajax request

My setup involved a basic nodejs server (including CORS) : var express = require('express'); var app = express(); var http = require('http').Server(app); var io = require('socket.io')(http); var port = 8001; http.listen(port, ...

Feeling trapped during the process of setting up a intricate jQuery Image Slider

I've hit a roadblock while trying to make changes to the slider located at THIS URL. In the current setup, each thumbnail corresponds to one main display image. Clicking on a thumbnail displays a single image and then proceeds to slide to the next th ...

Ways to toggle the sliding of text on and off an image?

After spending some time experimenting with my code, I managed to get it working. Essentially, when a user hovers over an image, text now appears over the image. Since this is a gallery, I had to utilize $(this).children in order to target and display the ...

Error message "TypeError: onClick is not a function" occurs when attempting to use a prop in a functional component

I am encountering issues while trying to utilize the onclick function as props. It shows an error message 'TypeError: onClick is not a function' when I click. What should I do? 7 | <Card 8 | onClick={() => onClick(dish ...

Database not receiving input data from AngularJS form submission

Having some trouble saving form data to the database using angularjs. Not sure what I'm doing wrong. Here's my HTML form: <form id="challenge_form" class="row" > <input type="text" placeholder="Challenge Name" ng-model="ch ...

Angular displaying a slice of the data array

After following the example mentioned here, and successfully receiving API data, I am facing an issue where only one field from the data array is displayed in the TypeScript component's HTML element. Below is the content of todo.component.ts file im ...