Arranging data in a JSON array while handling null values in JavaScript

Here is my JSON array:

var jData = [
{id: 1, parent: null},
{id: 2, parent: null},
{id: 3, parent: 1},
{id: 4, parent: 2},
{id: 5, parent: 2},
{id: 6, parent: 1}];

I would like to sort it in the following order (first by id then by parent):

[
    {id: 1, parent: null},
    {id: 3, parent: 1},
    {id: 6, parent: 1}
    {id: 2, parent: null},    
    {id: 4, parent: 2},
    {id: 5, parent: 2},
];

What is the most efficient way to achieve this in JavaScript?

I have attempted to use the following code, but with no success:

jData .sort((a, b) => a.id - b.id || a.parent - b.parent);

Please assist!

Answer №1

In order to properly organize the data, you must first implement a topological sorting algorithm to arrange the nodes based on their appearance.

function manipulateData(array) {
    return array.flatMap(({ information, children = [] }) => [information, ...manipulateData(children)]);
}

var data = [{ id: 1, parent: null }, { id: 2, parent: null }, { id: 3, parent: 1 }, { id: 4, parent: 2 }, { id: 5, parent: 2 }, { id: 6, parent: 1 }],
    tree = function (data, root) {
        var t = {};
        data.forEach(data => {
            Object.assign(t[data.id] = t[data.id] || {}, { data });
            t[data.parent] = t[data.parent] || {};
            t[data.parent].children = t[data.parent].children || [];
            t[data.parent].children.push(t[data.id]);
        });
        return t[root].children;
    }(data, null),
    result = manipulateData(tree);

console.log(result);
console.log(tree); // just to show what's happening
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

In cases where the parent is null, we assign the id as the parent value and proceed to sort by parent first in order to achieve the desired outcome. If the comparison between parent values results in a tie, we then sort by id.

var jData = [{id:5,parent:2},{id:1,parent:null},{id:4,parent:2},{id:2,parent:null},{id:3,parent:1},{id:6,parent:1}];

let res = jData.sort((a,b) => {
  let ap = a.parent ? a.parent : a.id,
      bp = b.parent ? b.parent : b.id;
  return ap - bp || a.id - b.id;
});

console.log(res);

Answer №3

If you want to organize each array based on its parent, you can utilize the reduce function. When the parent is null, assign it a value of 0. Another reduce can then be used to build the final array.

var data = [{"id":1,"parent":null},{"id":2,"parent":null},{"id":3,"parent":1},{"id":4,"parent":2},{"id":5,"parent":2},{"id":6,"parent":1}]

var temp = data.reduce((acc, cur) => {
  let parentNode = cur.parent || 0;
  acc[parentNode] = acc[parentNode] || [];
  acc[parentNode].push(cur);
  return acc;
}, {});

var organizedData = temp[0].reduce((acc, cur) => {
  var childArray = temp[cur.id] || [];
  childArray.sort((a, b) => a.id - b.id); // Sort in case the IDs are not sequential in the original array.
  acc.push(cur, ...childArray);
  return acc;
}, []);


console.log(organizedData);

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

How can I conditionally disable a button in Vue.js using an if statement?

Can someone help me figure out why all my buttons are getting disabled when I only want one to be disabled? Here is the code where I created a counter with vue.js: <body> <div id="app"> <button @click="co ...

What is the best way to combine dictionaries from multiple lists (JSONs) in Python?

I have a scenario where I have two sets of dictionaries retrieved from JSON data: the first set contains all objects, while the second set includes only objects with "Disk" as the name: list_of_dicts1 = [ {u'id' : u'111', u'hos ...

Using an array of objects to set a background image in a Bootstrap carousel using jQuery: a step-by-step guide

I have an array of items, each containing a background property with a URL to an image. Here is my array: https://i.sstatic.net/jfrV0.png Here is the HTML structure: <div id="myCarousel" class="carousel slide" data-ride="carousel"> <ol ...

Retrieve the quantity of files in a specific directory by implementing AJAX within a chrome extension

I need assistance with obtaining the count of images in a specific directory using JS and AJAX within my chrome extension. My current code is included below, but it does not seem to be functioning as expected since the alert is not displaying. main.js .. ...

Stable header that jumps to the top when scrolled

I have implemented the JavaScript code below to set the header to a fixed position when it reaches the top of the page so that it remains visible while the user scrolls. Everything appears to be functional, but the header movement is abrupt and not smooth. ...

Angular JavaScript does not take effect on elements inserted into ui-view

When transferring the code from main.html to index.html, the javascript functions smoothly. The click function successfully triggers the ripple effect. Link: Ripple Click Effect Google Material Design However, upon extracting the code to main.html and in ...

When retrieving data from an API, JSON serialization will handle any instances of blank or null

Hey there, I'm currently utilizing an API to fetch a list of availability requirements from a server before my app goes live. However, when these availability requirements are null, it causes the app to crash. I've made an attempt to address thi ...

Using Javascript to modify a json file

Currently, I have a command that adjusts the server prefix based on user input. Below is the code snippet I am currently utilizing: client.on('message', message => { if (message.content.toLowerCase().startsWith(',prefix')) { const ar ...

Updating the AngularJS view following a deletion process

I have a web application developed using AngularJS and Rails that carries out RESTful operations like create, read, and delete. After deleting an item, I need to refresh the page and update the view asynchronously. However, I am facing challenges in imple ...

Forcing a property binding update in Angular 2

Take a look at this particular component import {Component} from 'angular2/core' @Component({ selector: 'my-app', providers: [], template: ` <div> <h3>Input with two decimals</h3> <input type ...

Obtaining NodeJS from a mysterious subdirectory

-- plugins ---- myplugin1 ------ core ---- myplugin2 ------ core If this represents the directory structure, is there a method to import all core directories from plugins without specifying the specific plugin names like myplugin1? require('/plugins ...

Enable users to input their custom code and run it when the specified conditions are met

Currently, I am developing a Multi-tenant application that requires users to input their own code and run it under specific conditions. I have several ideas in mind, but I am unsure which approach would be most effective. All the proposed methods will ha ...

What is the best way to trigger an ajax request when a user selects a tab?

How can I trigger an ajax call when a tab is clicked by the user? What is the best way to handle the HTML response and display it within the tab? How do I bind JavaScript events to the dynamically loaded HTML content? I am familiar with using jQueryUI tab ...

JavaScript: The variable `scopes` is declared

I'm completely new to JavaScript. Can anyone help me understand why this code isn't working, and what changes I need to make to fix it? function getResults(keywords) { foo.foo = function() { var bar = foo.getSomeText; // ...

Create your own custom block on the frontend product page

I am trying to create a custom block on the Product Page of my Magento store. I attempted it like this: Magento- How can i add a new custom block in product details page using module Unfortunately, it did not work as expected. Did I make any mistakes he ...

Error in Typescript: The type 'Element' does not have a property named 'contains'

Hey there, I'm currently listening for a focus event on an HTML dialog and attempting to validate if the currently focused element is part of my "dialog" class. Check out the code snippet below: $(document).ready(() => { document.addEventListe ...

Ways to resolve BuildJobExitNonZero issue on Digital Ocean

Hey everyone, this is my first time using Digital Ocean. I'm trying to deploy my app via Launch App, and my code is hosted on GitHub. However, when I try importing the code and building it, I'm encountering the following error that I don't u ...

Save this as a data structure

ANSWER: Each key ending with :private contains a __get() and toJSON() method, which is essential for retrieving data from them since _propMap is private. I am utilizing PayPal's PHP API to process payments from PayPal. After completing a paym ...

Converting JSON to model in Flutter/Dart using a Map property

After receiving my API response, I noticed that the json object has dynamic keys for zones. { "workspaces": [ { "id": "1154237e8b6-7270-4c99-81e9-9d752e0c295c", "createdAt": " ...

Customizing Echart tooltip appearance

I've integrated echart () into my Vue.js application, and I'm attempting to personalize the tooltip on a ring chart. However, I'm facing challenges in achieving this customization. My goal is to show my own JSON data in the tooltip when hove ...