extracting values from deeply nested JSON array in JavaScript

Is there a way to extract values from a deeply nested JSON array?
I'm looking to retrieve all pairs of (nameValue and value) from the JSON provided below

  var json = [{
                name: 'Firstgroup',
                elements: [{
                    name: 'Field1',
                    elements: [{
                        name: 'country32',
                        elements: [{
                            nameValue: 'city1',
                            value: 2025
                        }]
                    }]
                },
                    {
                        name: 'Field2',
                        elements: [{
                            name: 'country22',
                            elements: [{
                                nameValue: 'city2',
                                value: 1875
                            }]
                        },
                            {
                                name: 'country12',
                                elements: [{
                                    nameValue: 'city3',
                                    value: 1810
                                }]
                            }]
                    }]
            },
                {
                    name: 'Secondgroup',
                    elements: [{
                        name: 'Field1',
                        elements: [{
                            name: 'country52',
                            elements: [{
                                nameValue: 'city4',
                                value: 1310
                            },
                                {
                                    nameValue: 'city5',
                                    value: 1125
                                }]
                        }]
                    },
                        {
                            name: 'Field3',
                            elements: [{
                                name: 'country42',
                                elements: [{
                                    nameValue: 'city6',
                                    value: 1100
                                }]
                            }]
                        }]
                }];

I have successfully extracted the first pair using the code snippet below

 function getDataProvider(array)
    {
        var dataPoint = [];
        var elements = 'elements';
        var name = 'nameValue';
        var value = 'value';

        var i, j, len;

       for (j = 0; j < array.length; j++) {
           i = array[j];
           if (i[elements]) {
               this.getDataProvider(i[elements]);
            } else {
               dataPoint.push({
                   name: i[name],
                   value: i[value]
               });
            }
        }
       return dataPoint;
    }    

How can I extract all pairs from the above JSON considering that the depth is variable and unknown, but will always include (nameValue and value) pairs?

Answer №1

To efficiently extract name-value pairs from nested elements, you can implement a recursive function that iterates through the structure, pushing valid pairs to a result array.

var extractNameAndValues = function(arr) {
  var nameValuePairs = [];
  for (var i = 0, len = arr.length; i < len; i++) {
    var item = arr[i];
    if (item.value && item.nameValue) {
      nameValuePairs.push(item);
    }
    if (item.elements) {
      nameValuePairs = nameValuePairs.concat(extractNameAndValues(item.elements));
    }
  }
  return nameValuePairs;
};

var json = [{
                name: 'Firstgroup',
                elements: [{
                    name: 'Field1',
                    elements: [{
                        name: 'country32',
                        elements: [{
                            nameValue: 'city1',
                            value: 2025
                        }]
                    }]
                },
                    {
                        name: 'Field2',
                        elements: [{
                            name: 'country22',
                            elements: [{
                                nameValue: 'city2',
                                value: 1875
                            }]
                        },
                            {
                                name: 'country12',
                                elements: [{
                                    nameValue: 'city3',
                                    value: 1810
                                }]
                            }]
                    }]
            },
                {
                    name: 'Secondgroup',
                    elements: [{
                        name: 'Field1',
                        elements: [{
                            name: 'country52',
                            elements: [{
                                nameValue: 'city4',
                                value: 1310
                            },
                                {
                                    nameValue: 'city5',
                                    value: 1125
                                }]
                        }]
                    },
                        {
                            name: 'Field3',
                            elements: [{
                                name: 'country42',
                                elements: [{
                                    nameValue: 'city6',
                                    value: 1100
                                }]
                            }]
                        }]
                }];

var result = extractNameAndValues(json);
var asString = "";
for (var i = 0, len = result.length; i < len; i++) {
  var item = result[i];
  asString += item.nameValue + ": " + item.value + "<br/>";
}
document.body.innerHTML = asString;

Answer №2

To obtain the desired properties in an array, you can utilize a combination of iterative and recursive techniques.

function fetchProperties(array) {
    var result = [];
    array.forEach(function iterate(obj) {
        if (obj.elements) {
            obj.elements.forEach(iterate);
            return;
        }
        result.push({ name: obj.nameValue, value: obj.value });
    });
    return result;
}

var data = [{ name: 'Firstgroup', elements: [{ name: 'Field1', elements: [{ name: 'country32', elements: [{ nameValue: 'city1', value: 2025 }] }] }, { name: 'Field2', elements: [{ name: 'country22', elements: [{ nameValue: 'city2', value: 1875 }] }, { name: 'country12', elements: [{ nameValue: 'city3', value: 1810 }] }] }] }, { name: 'Secondgroup', elements: [{ name: 'Field1', elements: [{ name: 'country52', elements: [{ nameValue: 'city4', value: 1310 }, { nameValue: 'city5', value: 1125 }] }] }, { name: 'Field3', elements: [{ name: 'country42', elements: [{ nameValue: 'city6', value: 1100 }] }] }] }],
    result = fetchProperties(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

This alternative approach generates an array for each recursive function call.

function fetchProperties(array) {
    return array.reduce((res, obj) => res.concat(
        obj.elements
            ? fetchProperties(obj.elements)
            : { name: obj.nameValue, value: obj.value }
    ), []);
}

var data = [{ name: 'Firstgroup', elements: [{ name: 'Field1', elements: [{ name: 'country32', elements: [{ nameValue: 'city1', value: 2025 }] }] }, { name: 'Field2', elements: [{ name: 'country22', elements: [{ nameValue: 'city2', value: 1875 }] }, { name: 'country12', elements: [{ nameValue: 'city3', value: 1810 }] }] }] }, { name: 'Secondgroup', elements: [{ name: 'Field1', elements: [{ name: 'country52', elements: [{ nameValue: 'city4', value: 1310 }, { nameValue: 'city5', value: 1125 }] }] }, { name: 'Field3', elements: [{ name: 'country42', elements: [{ nameValue: 'city6', value: 1100 }] }] }] }],
    result = fetchProperties(data);

console.log(result);
.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

JavaScript code not functioning on WordPress website (no impact)

I've encountered a strange problem. Here is the code snippet: (function($){ $("#maps1").hover( function(){$("#kontakt_os_1").hide();} ); $("#maps2").hover( function(){$("#kontakt_os_2").hide();} ); $("#maps3").hover( ...

Unveiling the secrets: Navigating and exploring a JSON feed

In my current code, I am making a call to the Google Maps API and parsing JSON data by using the following snippet: def getLocalityFromPostCode(postcode): import urllib, json import pprint url = "http://maps.googleapis.com/maps/api/geocode/jso ...

Why is the state object empty in this React Native function?

One React-Native component I have is responsible for rendering an image gallery in a list format. This component is called once for each item on the parent list. It takes two props: "etiqueta," which contains the title of the item, and "galleries," which i ...

using node.js to extract a cookie from a 302 redirect

Need help simulating a login using node.js. The request is a post method and returns a 302 status code. However, when trying to simulate the request in node, I encounter the following error: Error handling unrejected promise: StatusCodeError: 302 Upon i ...

Encountering a problem where a 'List<dynamic>' type is not recognized as a subtype of a 'Map<String, dynamic>' type

I am currently working on a flutter app that is meant to showcase users in a list format. While I have been successful in fetching and printing the data, displaying it presents an issue for me as I keep encountering this error message Exception has occurre ...

What is the best way to use the $push operation to add an object to an array within a mongoDB database using Node.js

I am trying to find a way to push an object into an array inside my MongoDB database. When using the $push method with submits[postDate], I am encountering an error with the syntax highlighting the first "[". Any suggestions on how to resolve this issue? ...

What are some ways to implement dangerouslySetInnerHTML in conjunction with read-more-react from npm?

Is there a way to include dangerouslySetInnerHTML in a text field without receiving an error? <ReadMoreReact text={yourTextHere} min={minimumLength} ideal={idealLength} max={maxLength} readMoreText={read ...

suggestions for organizing data in an AJAX/jQuery page

Welcome to my JavaScript/Ajax webpage that also utilizes jQuery. I am facing a challenge with displaying a nested structure. Once a top level element is displayed, users should be able to click on it and reveal the levels below (which are dynamically gene ...

When presented with a JSON string, transform the nested JSON structure into key value pairs. The key for each pair will be the name of the element hierarchy combined with an underscore

When presented with a json string, the task is to convert the nested json into key value pairs. Each key in the pairs should consist of the name of the element hierarchy followed by an underscore. { "person": { "id": 1, &quo ...

How to assign a specific class to a list item in AngularJS based on its attribute value

Having some difficulties with this code: .directive('mydirective', function() { return { template: '<ul>\ <li priority="500"><a href="#"><i></i>Inbox</a></li>\ ...

The link containing special characters like % cannot access the api

I am facing an issue with retrieving a signUrl from S3. When I make the call with special characters like %, my code does not parse it correctly and I receive a 404 not found error. Here is the ajax request I am using: My API setup: app.get('/websi ...

Storing a PDF created with Laravel in a queue

I have a tool that converts HTML to PDF and saves it locally. I also use a live URL to fetch another PDF and save it on my local machine. Then, I utilize a Laravel library to merge both PDFs into a single file through embedding. Previously, this process ...

A guide to integrating gatsby-remark-images-grid in markdown with Gatsby.js

Currently, I am working on creating a blog using Gatsby.js with markdown and I want to incorporate CSS grid into my blog posts to showcase a beautiful grid layout of images. I am aware that Gatsby offers incredible plugins to address various challenges. ...

The smooth scroll feature is not functioning properly on the animated mouse-scroll down button

I've recently added an Animated Mouse Scroll Down button on my website. However, when I click the button, the smooth scroll feature is not working as expected. Important Note: I already have a separate button for navigating to the next section where ...

Error encountered: unable to locate module - '@deck.gl/exper-layers'

When attempting to run npm start on the trip example in deck.gl, I encountered an issue. Although other examples open without any problems, the trip example is giving me this npm error: Module not found: Error: Can't resolve '@deck.gl/experim ...

Tips for managing lag caused by large raw image re-renders in a React application

When trying to change the background position of a user-uploaded background image that is in raw Data URI format using CSS, I noticed that re-rendering becomes slow if the image size exceeds 1mb. This issue does not occur with smaller images. Is there a ...

utilize jQuery and AngularJS to transform a JSON object into a nested JSON structure

Is there a way to convert my current JSON file into a nested JSON structure like the one below? I've attempted various methods (How to convert form input fields to nested JSON structure using jQuery), but I'm not achieving the desired outcome. Ca ...

Accessing nested objects within a JavaScript array for an Express API

My current data sample looks like this: var data = [{ articles : [{ id : '0', url : 'foo', title : 'Foo', body : 'some foo bar', category : 'foo', tags : ...

Passing a particular method of a specific instance as an argument

I am interested in creating a class that allows me to specify "For instance a1 of A, you will call the function computeValue() of a specific instance b1 of B when the value is needed". It's important for me to indicate which method of which instance w ...

Retrieving values from multiple inputs in NightwatchJS

Can nightwatchjs be used to retrieve values from multiple inputs simultaneously? I am looking to verify the values of several input fields at once. Your help is much appreciated. ...