Unraveling the complexities of parsing deeply nested object notation - is there no end in

I'm currently grappling with the task of converting this object hash:

"food": {
    "healthy": {
        "fruits": ['apples', 'bananas', 'oranges'],
        "vegetables": ['salad', 'onions']
    },
    "unhealthy": {
        "fastFood": ['burgers', 'chicken', 'pizza']
    }
}

into a format like this:

food:healthy:fruits:apples
food:healthy:fruits:bananas
food:healthy:fruits:oranges
food:healthy:vegetables:salad
food:healthy:vegetables:onions
food:unhealthy:fastFood:burgers
food:unhealthy:fastFood:chicken
food:unhealthy:fastFood:pizza

In essence, it involves looping through the object while keeping track of the path and generating the desired output.

However, I'm unsure how to recursively loop until all nested elements are processed.

var path;
var pointer;
function loop(obj) {
    for (var propertyName in obj) {
        path = propertyName;
        pointer = obj[propertyName];

        if (pointer typeof === 'object') {
            loop(pointer);
        } else {
            break;
        }        
    }
};

function parse(object) {
    var collection = [];

};

There are two conflicting issues at play here:

  1. If I use recursive programming, it loses track of properties that have already been parsed.
  2. If I don't use recursion, I can't handle infinite nesting.

Any ideas on how to tackle this challenge would be greatly appreciated.

Best regards

Answer №1

The issue with your recursive function stems from storing the state externally rather than within the function itself. To address this, it is essential to contain the state inside the function so that each iteration can keep track of its own state.

Consider implementing the following structure:

var obj = /* ... the object ... */;
var lines = traverse([], "", obj);

function traverse(lines, prefix, obj) {
    var key, encounteredValue = false;

    // Check if it's an array
    if (Object.prototype.toString.call(obj) === "[object Array]") {
        // Since all values in your example are strings added at the end, follow through with that operation
        for (key = 0; key < obj.length; ++key) {
             lines.push(prefix + ":" + obj[key]);
        }
    }
    else {
        // If it's not an array, it must be an object. Recurse for each property and include the property in the prefix on every line
        for (key in obj) {
            traverse(lines, prefix ? (prefix + ":" + key) : key, obj[key]);
        }
    }

    return lines;
}

This solution is impromptu and untested, but it conveys the concept effectively.

Update: Surprisingly, the solution appears to be effective, as demonstrated by Michael Jasper who kindly provided a live demo (source) which has been slightly adjusted.

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

I encountered an error from DataTables when trying to set the width of the header cells using the original width of the columns

                 Help! I keep getting an error message: DataTable Uncaught TypeError: Cannot read property 'style' of undefined Does anyone have any ideas on how to fix this?   I keep seeing the following error message: Uncaught Typ ...

Some filters in Bootstrap table not displaying properly

I've been struggling to showcase this bootstrap table with the data-filter-control attribute, but I'm unable to achieve it successfully. The filters are failing in two main ways: The filter is not showing all the categories from that column The ...

Is the button inactive until an action is taken?

In my coding project, I am working with two buttons. I am trying to figure out a way to disable the second button until the first button is clicked. Does anyone have any suggestions on how to achieve this using a combination of JavaScript and CSS? ...

The AXIOS method in Express.js is designed to return a Promise object that may contain an

I am currently learning ExpressJS and Axios I have created a folder named utils and placed the axios.js file const axios = require('axios'); loadDataPesan=async function(opts){ axios.get('localhost/getData', { params ...

Functioning properly on Firefox, Bootstrap modal encounters issues on Chrome

The following code snippet demonstrates closing one modal, opening another, and executing a parsing function upon button click: $('#BtnUpCsv').on('click', function (e) { $('#csvModal').modal('hide'); $(&a ...

Do you have to host a node server to run Angular applications?

(say) I am currently working on a project that utilizes Laravel or PHP for the back-end and Angular for the front-end. In my setup, I am using angular.js files from a CDN, which should work fine. However, I find myself confused when tutorials and books me ...

The Material UI read-only rating component fails to update even after the data has been successfully loaded

I have a rating component in my child component, and I am passing data from the parent component through props. However, there seems to be an issue with the MUI rating value not updating when the data is ready for viewing. https://i.sstatic.net/bqSfh.jpg ...

Unexpected unhandled_exception_processor in Google Chrome

I keep encountering a strange uncaught exception handler in Google Chrome. After updating all follow buttons to download JavaScript asynchronously, I noticed an error in the content.js file mentioned in the exception message which advises against polluting ...

Include a hyperlink within every row - ngx-datatable

I am brand new to using Angular. My goal is to have a link on each row of ngx-datatable that directs me to another page when clicking on the first column of each row. This new page should be based on the row id. For example, if I have a table listing cours ...

Experiencing duplicate execution of $onChanges in AngularJS version 1.6

I might be overthinking this, but that's why I'm seeking help. :) Note: In the example below, the controller alias for the component is "ctrl". var ctrl = this; Imagine we have a component with two bindings, one of which is optional: bindings: ...

Preventing pageup/pagedown in Vuetify slider: Tips and tricks

I am currently using Vuetify 2.6 and have integrated a v-slider into my project. Whenever the user interacts with this slider, it gains focus. However, I have assigned PageUp and PageDown keys to other functions on the page and would like them to continue ...

Setting the className in Next.js without using {styles.red} can be achieved by directly passing the

Description I'm trying to use just the pure class name without the {styles.class-name} convention in Next.js. After doing some research, I discovered that I need to configure the next.config.js file. Does anyone have good references for this? Current ...

Guide on building a "like" button using a Node.js Express application

I am in the process of developing a website using node, express, and mongodb. I am facing an issue with passing a variable value from my ejs file to the server side. Can someone help me solve this problem? Here is what I have attempted so far: Example Ht ...

Programmatically changing the stylesheet does not seem to be working to apply the

I'm currently working on a feature that allows the User to customize the application's style. Index.html <!DOCTYPE html> <html> <head> <link id="style" rel="stylesheet" type="text/css" href="red-stylesheet.css" ...

Sorting an array of objects keys according to the position of keys in another array

I have two arrays: one with the correct order of keys and values, and another array coming from a backend in an unsorted format. let arr1 = ['name', 'age', 'occupation', 'address'] let arr2 = [{'age': 20, ...

Tips for displaying a page with an unchecked checkbox on bootstraptable

Recently, I've been working with bootstraptable, but I've been struggling to figure out how to load the page with the sort boxes unchecked. I've read through the documentation multiple times, but all of the functions seem to be centered arou ...

Invoke index functions within a component

I have a widget/component written in Angular 4 within the index.html file. Before and after this angular app, there are various HTML elements due to the nature of it being an additional component for the website. The head section of the index file include ...

Tips for saving HTML Canvas content to Google Storage

My goal is to save the content of an HTML canvas to Google Storage. Here is my approach: Generate a signed URL for the image file. class ThumbnailUploadSignedURL(APIView): @method_decorator(login_required(login_url='/login/')) def post(s ...

Is there a way to target a sibling element of another element by using its identifier in Cypress?

My current task involves clicking a checkbox within a list of table rows. The only way I can think of reaching this level is by targeting the span tag along with its corresponding name. cy.get('tr > td > span').contains('newCypressTes ...

Leveraging object values from ng-repeat as parameters in JavaScript

I need help with a code snippet I'm working on. Here is what it looks like: <tr ng-repeat="obj in objs"> <td onClick = "someFunction({{obj.val1}})">{{obj.val2}}</td> <td>{{obj.val3}}</td> </tr> While the colum ...