What is the best method for transforming a nested object into an array of objects?

This object contains nested data

var arr = [{
    "children": [{
        "children": [{
            "children": [],
            "Id": 1,
            "Name": "A",
            "Image": "http://imgUrl"
        }],
        "Id": 2
        "Name": "B",
        "Image": "http://imgUrl"
    }],
    "Id":3,
    "Name": "C",
    "Image": "http://imgUrl"
}]

The goal is to transform the above structure into this format:

[{
    "Name": "C",
    "Id": 3,
    "Image": "http://imgUrl"
}, {
    "Name": "B",
    "Id": 2,
    "Image": "http://imgUrl"
}, {
    "Name": "A",
    "Id": 1,
    "Image": "http://imgUrl"
}]

Below is the original conversion function:

    var newArr = []
    function getNestedObj(obj){

        if(obj.length){
            for ( var i=0; i<obj.length; i++){
                var newObj = {};
                newObj.Name = obj[i].Name;
                newObj.Id = obj[i].Id;
                newObj.Image = obj[i].Image;
                newArr.push(newObj);

                if(obj[i].children.length !=0 ){
                    getNestedObj(obj[i].children)
                }
                else {
                    return newArr;
                }
        }
       }
    }

How can I simplify this function?

Answer №1

Give this a try:

let arr = [{"children":[{"children":[{"children":[],"Id":1,"Name":"A","Image":"http://imgUrl"}],"Id":2,"Name":"B","Image":"http://imgUrl"}],"Id":3,"Name":"C","Image":"http://imgUrl"}];

function gatherChildren(a, r=[]) {
  a.forEach(({children, ...rest}) => {
    r.push(rest);
    if(children) gatherChildren(children, r);
  });
  return r;
}
let finalResult = gatherChildren(arr);
console.log(finalResult);

Answer №2

Recursive Function to Fill with Children:

const populateChildren = (arr = []) =>
arr.reduce(
    (filledArray, { children, ...others }) =>
        filledArray
            .concat(others)
            .concat(populateChildren(children)),
    [],
);
populateChildren(arrayToPopulate);

Answer №3

One way to achieve this is by using a recursive reduce function.

arr.reduce (function spr (res, cur) {
    let obj = {...cur}
    let children = obj.children
    delete obj.children;
    return children.reduce (spr, res).concat ([{
        ...obj
    }])
}, [])

let result = arr.reduce (function spr (res, cur) {
    let obj = {...cur}
    let children = obj.children;
    delete obj.children;
    return children.reduce (spr, res).concat ([{
      ...obj
    }])
}, [])

console.log (result)
<script>
var arr = [{
    "children": [{
        "children": [{
            "children": [{
                "children": [],
                "Id": 1,
                "Name": "A",
                "Image": "http://imgUrl"
            }],
            "Id": 1,
            "Name": "A",
            "Image": "http://imgUrl"
        }],
        "Id": 2,
        "Name": "B",
        "Image": "http://imgUrl"
    }],
    "Id":3,
    "Name": "C",
    "Image": "http://imgUrl"
}
, {
    "children": [{
        "children": [{
            "children": [],
            "Id": 1,
            "Name": "A",
            "Image": "http://imgUrl"
        }],
        "Id": 2,
        "Name": "B",
        "Image": "http://imgUrl"
    }],
    "Id":3,
    "Name": "C",
    "Image": "http://imgUrl"
}]
</script>

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

Leveraging React's State Values and Props

Can you help me with a React component challenge? I have two components that I need to work with: <select> <mytable> I want to build a new component called <myInterface>. The state of <myInterface>, let's call it S, needs to ...

Extracting live content from a website within a native Webview

Running an eCommerce website along with a simple mobile app for both iOS and Android that features a basic tab bar menu, including icons like a shopping cart, profile, refresh button, etc., as well as a Webview to display the website content. The App' ...

The functionality of using multiple inputs with Google Places API is not functioning as expected

Having trouble with the Google Place API. I am unable to set up 2 input fields with autocomplete. The first input is populated from a payload received from the backend, while the second input is within a Bootstrap modal. I have tried various solutions fou ...

Having trouble dynamically assigning the ng-model attribute

I am trying to populate the ArrayINeed array, which is the object I need to pass back to the API call. Currently, I am getting undefined for "ConfirmedTrackingReferenceNumbers": Dc.ArrayINeed. Despite researching various posts online and on SO, I have been ...

Unexpected Behavior Arises from Axios Get API Request

Below is a functional example in my CodePen showing what should be happening. Everything is working as intended with hard coded data. CodePen: https://codepen.io/anon/pen/XxNORW?editors=0001 Hard coded data: info:[ { "id": 1, "title": "Title one ...

Insert a new <tr> element into a dynamic table using PHP and jQuery without the need to refresh the page

I am attempting to dynamically insert a row into an existing table when a button is clicked. The rows in the table are created dynamically based on data retrieved from a PHP script. My approach involves making an ajax call to the insert_tr.php script, whi ...

I am facing issues with my submit buttons as they are not functioning

Once I hit the submit buttons, there seems to be an issue with redirecting to another page. Could anyone assist in identifying the error within this code and why my buttons "typ1" and "cod" are not redirecting to the specified location? <?php inc ...

What is the best way to incorporate a class creation pattern in Typescript that allows one class to dynamically extend any other class based on certain conditions?

As I develop a package, the main base class acts as a proxy for other classes with members. This base class simply accepts a parameter in its constructor and serves as a funnel for passing on one class at a time when accessed by the user. The user can spe ...

Similar to AngularJS, jQuery also provides a powerful tool for submitting forms

Recently, I've delved into the world of angularjs and have been truly amazed by its capabilities so far. One thing that took me by surprise was the lack of a simple solution for sending AJAX requests using the $http service. After hours of searching G ...

What are the reasons for the various methods available for importing my JS code?

Here is the structure of my folders: --public ----frontend.js --views ----fontend.ejs The frontend.js file is located inside the public folder, while the frontend.ejs file is in the views folder. In my HTML / EJS file, I included the JavaScript (fronten ...

Ways to stop the default action in a confirm dialog while using Angular JS

Within my save function, I have the following: $scope.saveData = function () { if (confirm("Are you sure you want to save") === false) { return } // do saving When using the above code and clicking "yes," I encounter an error. Interestin ...

Popstate functionality not functioning correctly, requiring multiple consecutive clicks

I am currently delving into the world of History Web API, but I've encountered my first challenge. While I have successfully implemented history.pushState, I am facing difficulties with popstate. It works perfectly the first time after an AJAX page l ...

What is the best way to output a JSX element using an inline switch statement?

I have been attempting to use an inline switch in order to return an element, but all I am getting is an empty <span> </span>. What could be the issue here? getRowTdForHeader: (header: string, entry: response) => { return (< ...

Updating PostgreSQL data by removing a key/value pair from a JSONB column

Looking at the table and data provided: CREATE TABLE test ( slots jsonb ); INSERT INTO test VALUES ('{"0": {"tag": "abc", "info": "xyz"}, "1": {"tag": "def", "in ...

Retrieve the list of device tokens for the APNS service

Is it possible to retrieve a list of all device tokens on which my app is installed through an APNS endpoint? I am aware of the feedback service that provides the status of devices to whom messages are sent, but I believe this is only after the message ...

Switching the endpoint renders the middleware ineffective

I've encountered a puzzling issue with my NodeJs - Express server, which serves as the backend for my mobile application. The problem arises when I send post requests to certain endpoints like checkmail and checkusername using axios from the frontend ...

Searching in real-time with ajax in CodeIgniter framework is a seamless and efficient process

I'm a beginner in CodeIgniter and eager to learn. Currently, I'm facing an issue where the data is not being populated on the search page. In the model: function fetch_data($query) { $this->db->select('*'); $this-> ...

Relaunch node.js in pm2 after a crash

Based on this post, it seems that pm2 is supposed to automatically restart crashed applications. However, when my application crashes, nothing happens and the process no longer appears in the pm2 list. Do I need to enable an 'auto restart' featu ...

Troubleshooting 404 errors with Cordova, AngularJS, and Node.js (Express) when using $http with

I'm currently testing in an Android environment using Cordova, AngularJS, and Node.js (Express). I'm attempting to retrieve some data using $http(), but consistently encountering a 404 error message (as seen in the alert below). Here's the ...

Updating dynamic parameter in a NextJS 13 application router: A complete guide

In my route user/[userId]/forms, I have a layout.tsx that includes a Select/Dropdown menu. The dropdown menu has options with values representing different form IDs. When the user selects an item from the dropdown, I want to navigate to user/[userId]/form ...