Exploring a JSON Object with Nested Data

I am trying to recursively parse a JSON object in JavaScript.

Below is an example of the JSON structure:

const obj = {
  tag: 'AA',
  type: 'constructed',
  value: 'ABCD1',
  child: [
    {
      tag: 'BB',
      type: 'constructed',
      value: 'ABCD2',      
      child: [
        {
          tag: 'CC',
          type: 'constructed',
          value: 'ABCD3',          
          child: [
            {
              tag: 'DD',
              type: 'primitive',
              value: 'ABCD4',
              child: []
            },
            {
              tag: 'EE',
              type: 'constructed',
              value: 'ABCD5',
              child: [
                {
                  tag: 'FF',
                  type: 'primitive',
                  value: 'ABCD6',
                  child: []
                },
                {
                  tag: 'GG',
                  type: 'primitive',
                  value: 'ABCD7',
                  child: []
                }                
              ]
            },
            {
              tag: 'HH',
              type: 'primitive',
              value: 'ABCD8',
              child: []
            }  
          ]
        }
      ]
    },
    {
      tag: 'II',
      type: 'primitive',
      value: 'ABCD9',
      child: []
    }  
  ]
}

The desired output should resemble this format:

{
  "AA": [
    {
      "BB": [
        {
          "CC": [
            {
              "DD": "ABCD4"
            },
            {
              "EE": [
                {
                  "FF": "ABCD6"
                },
                {
                  "GG": "ABCD7"
                }
              ]
            },
            {
              "HH": "ABCD8"
            }
          ]
        }
      ]
    },
    {
      "II": "ABCD9"
    }
  ]
}

The logic is that objects with type constructed should be nested within another object, while those with type primitive should directly have a key-value pair. The depth of the object can vary, and it may contain both constructed and primitive objects on the same level.

Currently, I have implemented the following code:

let jsonOutput = {}
parseData(obj, jsonOutput)

function parseData(jsonToParse, jsonOutput) {
  const type = jsonToParse.type
  const tag = jsonToParse.tag
  const value = jsonToParse.value
  let prev = jsonOutput
  
  if (type === 'constructed') {
    prev[tag] = []
    return parseData(jsonToParse.child[0], prev[tag])
  } else if (type === 'primitive') {
    prev[tag] = value
    return parseData(jsonToParse.child, prev[tag])    
  }
}

You can see my implementation in action at this fiddle: https://jsfiddle.net/kzaiwo/0v6a2tp8/16/

However, I'm struggling to make it iterate through the entire object. Recursion is not my forte, but I believe it's the most efficient way to handle this task. Can someone please assist me in finding what I'm missing? Any help would be greatly appreciated!

Thank you!

Answer №1

Here is a helpful code snippet for you:

const obj = { tag: 'AA', type: 'constructed', value: 'ABCD1', child: [ { tag: 'BB', type: 'constructed', value: 'ABCD2', child: [ { tag: 'CC', type: 'constructed', value: 'ABCD3', child: [ { tag: 'DD', type: 'primitive', value: 'ABCD4', child: [] }, { tag: 'EE', type: 'constructed', value: 'ABCD5', child: [ { tag: 'FF', type: 'primitive', value: 'ABCD6', child: [] }, { tag: 'GG', type: 'primitive', value: 'ABCD7', child: [] } ] }, { tag: 'HH', type: 'primitive', value: 'ABCD8', child: [] } ] } ] }, { tag: 'II', type: 'primitive', value: 'ABCD9...

function parseData(obj) {

const result = {};

if (obj.type === 'primitive') {
    result[obj.tag] = obj.value;
} else if (obj.type === 'constructed') {
    result[obj.tag] = obj.child.map(parseData);
}

return result;
}

const parsedJson = parseData(obj);
console.log(parsedJson);

Answer №2

Here's a concise and efficient reduceObj(obj) function that utilizes recursion:

const obj = { tag: 'AA', type: 'constructed', value: 'ABCD1', child: [ { tag: 'BB', type: 'constructed', value: 'ABCD2', child: [ { tag: 'CC', type: 'constructed', value: 'ABCD3', child: [ { tag: 'DD', type: 'primitive', value: 'ABCD4', child: [] }, { tag: 'EE', type: 'constructed', value: 'ABCD5', child: [ { tag: 'FF', type: 'primitive', value: 'ABCD6', child: [] }, { tag: 'GG', type: 'primitive', value: 'ABCD7', child: [] } ] }, { tag: 'HH', type: 'primitive', value: 'ABCD8', child: [] } ] } ] }, { tag: 'II', type: 'primitive', value: 'ABCD9', child: [] } ] }

function reduceObj(obj) {
  return { [obj.tag]: obj.type === 'primitive'
    ? obj.value
    : obj.child.map(reduceObj) };
}

const result = reduceObj(obj);
console.log(result);

For older versions of JavaScript, here is the equivalent syntax for the reduceObj function:

    function reduceObj(obj) {
      let o = {};
      o[obj.tag] = obj.child.map(function(childObj) {
        return obj.type === 'primitive'
          ? obj.value
          : reduceObj(childObj);
      });
      return o;
    }

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

When executing a JavaScript program, an error with the message 'MODULE_NOT_FOUND' appeared, causing the internal module loader in Node to throw an error at line 1145

node:internal/modules/cjs/loader:1145 throw err; ^ Error: Module 'C:\Users\sande\3D Objects\JavaScript-Lesson\lesson08.js' not found at Module._resolveFilename (node:internal/modules/cjs/loader:1142:15) at Mo ...

Error: The function cannot be performed on _nextProps.children

I'm having trouble implementing react context with nextJS and I keep encountering this error: Server Error TypeError: _nextProps.children is not a function This is my code for _App.js: import Head from "next/head"; import Router from &q ...

Add a container element resembling a div inside a table without implementing the table layout

I am working with a table that is rendered by DataTable, and I have the requirement to dynamically append new elements inside the table like this: The dark grey area represents the new DOM elements that need to be inserted dynamically. The first row cont ...

What are alternative ways to add an HTML snippet to an existing file without relying on jQuery?

Is it possible to inject the entire content of an HTML file, including all tags, into a specific div using only JavaScript? Alternatively, would it be necessary to append each element individually and create a function for this purpose? ...

Guide to personalizing the ngxDaterangepickerMd calendaring component

I need to customize the daterangepicker library using ngxDaterangepickerMd in order to separate the start date into its own input field from the end date. This way, I can make individual modifications to either the start date or end date without affectin ...

What is the procedure for formatting the body of a post as json format?

I am attempting to replicate a post request using Python requests. The post body is nonce=b3272d453ca8734f8df1c78ce201f00c&from=01%2F12%2F22&to=31%2F12%2F22&columns%5B%5D=Transaction.DateTimeConverted&columns%5B%5D=Terminal.Id I have succ ...

What are the steps for configuring a dynamic variable?

One issue I encountered was setting up a variable in vue that updates when the screen orientation changes. Despite adding this variable to the data object, it did not become reactive as expected. This is my initial data function for the component: data() ...

Divs expanding below content in IE on a particular server

Currently, I am facing an issue with a JavaScript div that expands correctly over other content in most situations but goes under the content in one specific scenario. I am unsure about where to begin debugging this problem. To provide some context, the d ...

Even after hitting ctrl+z, Node.js continues to listen on the port

I've been exploring some features of Node on Ubuntu, and I encountered an issue where even after pressing ctrl+z in my console to stop the server (to update my code changes), Node would still be listening on port 3000. This meant that every time I nee ...

What is the best way to save newly added elements on a webpage that were submitted by the

I am looking for a way to save the changes made by users on my webpage so that they can navigate to different pages and come back without losing any added elements. These changes should be retained even when the user goes back to edit the webpage, but I pr ...

Can you explain the distinction between angular-highcharts and highcharts-angular?

Our team has been utilizing both angular-highcharts and highcharts-angular in various projects. It appears that one functions as a directive while the other serves as a wrapper. I'm seeking clarification on the distinctions between the two and recomme ...

The shadows in Three Js are functioning correctly, although there are a few shadow lines visible below my model

I am currently in the process of modifying a three.js scene, despite having little experience with javascript and three.js. After successfully adding a shadow to my GLTF model, I noticed some yellow and red lines beneath the model that I cannot identify or ...

Concealed Input Enhancements for AutoComplete

Hey there! I'm new to AJAX and could really use some help with my autocomplete function. I'm trying to store the ID of the user's selection in a hidden input field, but I've hit a roadblock. So far, my function isn't working as exp ...

jQuery carousel displaying a blank slide at the conclusion

I am experiencing an issue with my slideshow where it shows an empty slide after the last element. I suspect that there is something in my script causing this behavior, as it seems to be finding one extra child for the element and adding it as an empty spa ...

Step-by-step guide on extracting checkbox value from response in Angular JS

Successfully added a checkbox value to the database. An issue arises when checking a checkbox after receiving a response, as the checked value displays as -1 instead of 0, 1, or 2. When clicking on a checked box, its index value should change to -1, bu ...

Step-by-step guide to implementing dynamic field autocomplete using AJAX techniques

Seeking assistance in merging ajax autocomplete with dynamic field input. The autocomplete feature is currently working on the first field, but when adding another field, the autocomplete stops functioning. Any help would be greatly appreciated. Here is t ...

Can you explain the significance of this code snippet 'true <=> false'?

Today I came across this piece of code: true <=> false. I'm a bit confused by it and don't really understand how it works. If anyone could shed some light on this expression for me, I would greatly appreciate it. For reference, this code ...

Ajax: What could be causing the post request to be triggered twice?

I am puzzled by the fact that my request is being sent twice, without any clear reason. Here is the code for my simple form: <form method="POST" class="mb-4" autocomplete="off" action="/recipe/add" novalidate id="form"> <div class="form-grou ...

JavaScript Transforming an Array into an Object

After working with node and redis for a while, I've encountered an issue. When using hgetall in redis, it returns an object. { uid: '6203453597', first_name: 'Name', last_name: 'Surname', gender: 'male& ...

Navigating JSON with Java/Jackson

I am currently working on a Java application to parse JSON data from the Reddit API. The sample JSON data I am trying to parse is structured like this: [ { "kind": "Listing", "data": { "modhash": "1jq62oyvwe15aaba7eb18b0b4363b567a007507663 ...