Recursively get the 'id' keys of a nested object in Javascript

I have a nested object which can be of any depth

[
    {
        "id": "3",
        "user_id": "1479",
        "folder_id": "2",
        "is_folder": true,
        "folder_name": "folder 3",
        "unique_filename": null,
        "original_filename": null,
        "file_extension": null,
        "content_type": null,
        "file_size": null,
        "description": "People",
        "visible": false,
        "status": 0,
        "deleted_at": null,
        "last_access": "2022-11-21T09:34:48.546+02:00",
        "created_at": "2022-11-21T09:34:48.546+02:00",
        "updated_at": "2022-11-21T09:34:48.546+02:00",
        "children": [
            {
                "id": "36",
                "user_id": "1479",
                "folder_id": "3",
                "is_folder": true,
                "folder_name": "folder 4",
                "unique_filename": null,
                "original_filename": null,
                "file_extension": null,
                "content_type": null,
                "file_size": null,
                "description": "People",
                "visible": false,
                "status": 0,
                "deleted_at": null,
                "last_access": "2022-11-21T21:33:48.767+02:00",
                "created_at": "2022-11-21T21:33:48.767+02:00",
                "updated_at": "2022-11-21T21:33:48.767+02:00",
                "children": [
                    {
                        "id": "37",
                        "user_id": "1479",
                        "folder_id": "36",
                        "is_folder": true,
                        "folder_name": "folder 37",
                        "unique_filename": null,
                        "original_filename": null,
                        "file_extension": null,
                        "content_type": null,
                        "file_size": null,
                        "description": "People",
                        "visible": false,
                        "status": 0,
                        "deleted_at": null,
                        "last_access": "2022-11-21T21:38:30.690+02:00",
                        "created_at": "2022-11-21T21:38:30.690+02:00",
                        "updated_at": "2022-11-21T21:38:30.690+02:00",
                        "children": []
                    }
                ]
            },
            {
                "id": "42",
                "user_id": "1479",
                "folder_id": "3",
                "is_folder": true,
                "folder_name": "folder 41",
                "unique_filename": null,
                "original_filename": null,
                "file_extension": null,
                "content_type": null,
                "file_size": null,
                "description": "People",
                "visible": false,
                "status": 0,
                "deleted_at": null,
                "last_access": "2022-11-21T23:38:31.935+02:00",
                "created_at": "2022-11-21T23:38:31.935+02:00",
                "updated_at": "2022-11-21T23:38:31.935+02:00",
                "children": []
            }
        ]
    },
    {
        "id": "5",
        "user_id": "1479",
        "folder_id": null,
        "is_folder": false,
        "folder_name": null,
        "unique_filename": "drives/users/user_drive_1479/YTHGg4dnzn8O5a4DGHbntsrKhY2n4ycc3hZG5j7YxdIb5yEka9iToJDi9WxQPe4taSjLP53b1s01mctIy69o7m6L92.c",
        "original_filename": "sample3.c",
        "file_extension": "c",
        "content_type": "text/x-c",
        "file_size": "126",
        "description": null,
        "visible": false,
        "status": 0,
        "deleted_at": null,
        "last_access": "2022-11-21T09:37:48.766+02:00",
        "created_at": "2022-11-21T09:37:48.767+02:00",
        "updated_at": "2022-11-21T09:37:48.767+02:00",
        "children": []
    },
    {
        "id": "7",
        "user_id": "1479",
        "folder_id": null,
        "is_folder": false,
        "folder_name": null,
        "unique_filename": "drives/users/user_drive_1479/FSix4WZx0s9ey89x3foLxmaC1wCHTSw1HQi8fDxQ32bYQyKmyPJBcgeI33KOrdPfAcOChvkBnIBizj5IQbggeprCpz.cpp",
        "original_filename": "sample1.cpp",
        "file_extension": "cpp",
        "content_type": "text/x-c",
        "file_size": "94",
        "description": null,
        "visible": false,
        "status": 0,
        "deleted_at": null,
        "last_access": "2022-11-21T09:37:52.324+02:00",
        "created_at": "2022-11-21T09:37:52.324+02:00",
        "updated_at": "2022-11-21T09:37:52.324+02:00",
        "children": []
    },
    {
        "id": "37",
        "user_id": "1479",
        "folder_id": "36",
        "is_folder": true,
        "folder_name": "folder 37",
        "unique_filename": null,
        "original_filename": null,
        "file_extension": null,
        "content_type": null,
        "file_size": null,
        "description": "People",
        "visible": false,
        "status": 0,
        "deleted_at": null,
        "last_access": "2022-11-21T21:38:30.690+02:00",
        "created_at": "2022-11-21T21:38:30.690+02:00",
        "updated_at": "2022-11-21T21:38:30.690+02:00",
        "children": []
    }
]

I need to get the value of all the id keys

from the array of objects above the expected outcome would be

[3,36,37,42,5,7,37]

the code I have tried is shown below

    if (data.children) {
      console.log(data.id)
      data.children.forEach(item => {
        this.getObject(item)
      })
    } else {
      console.log(data.id)
    }

the data variable being the array of objects above

I get undefined as a result.

your assistance would be much appreciated

>Solution :

Using a recursive technique can cause a stack overflow if the node treelist is too numerous. An iterative approach is safer:

TS Playground

type NodeWithChildren<T> = T & { children?: T[] };

function collectNodeValues <
  K extends string,
  T extends NodeWithChildren<Record<K, unknown>>,
>(nodeList: readonly T[], targetProperty: K): T[K][] {
  const stack: T[] = [...nodeList];
  const values: T[K][] = [];

  while (stack.length > 0) {
    const node = stack.shift()!;
    values.push(node[targetProperty]);
    if (!Array.isArray(node.children)) continue;
    stack.unshift(...node.children);
  }

  return values;
}

const input = [{"id":"3","user_id":"1479","folder_id":"2","is_folder":true,"folder_name":"folder 3","unique_filename":null,"original_filename":null,"file_extension":null,"content_type":null,"file_size":null,"description":"People","visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T09:34:48.546+02:00","created_at":"2022-11-21T09:34:48.546+02:00","updated_at":"2022-11-21T09:34:48.546+02:00","children":[{"id":"36","user_id":"1479","folder_id":"3","is_folder":true,"folder_name":"folder 4","unique_filename":null,"original_filename":null,"file_extension":null,"content_type":null,"file_size":null,"description":"People","visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T21:33:48.767+02:00","created_at":"2022-11-21T21:33:48.767+02:00","updated_at":"2022-11-21T21:33:48.767+02:00","children":[{"id":"37","user_id":"1479","folder_id":"36","is_folder":true,"folder_name":"folder 37","unique_filename":null,"original_filename":null,"file_extension":null,"content_type":null,"file_size":null,"description":"People","visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T21:38:30.690+02:00","created_at":"2022-11-21T21:38:30.690+02:00","updated_at":"2022-11-21T21:38:30.690+02:00","children":[]}]},{"id":"42","user_id":"1479","folder_id":"3","is_folder":true,"folder_name":"folder 41","unique_filename":null,"original_filename":null,"file_extension":null,"content_type":null,"file_size":null,"description":"People","visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T23:38:31.935+02:00","created_at":"2022-11-21T23:38:31.935+02:00","updated_at":"2022-11-21T23:38:31.935+02:00","children":[]}]},{"id":"5","user_id":"1479","folder_id":null,"is_folder":false,"folder_name":null,"unique_filename":"drives/users/user_drive_1479/YTHGg4dnzn8O5a4DGHbntsrKhY2n4ycc3hZG5j7YxdIb5yEka9iToJDi9WxQPe4taSjLP53b1s01mctIy69o7m6L92.c","original_filename":"sample3.c","file_extension":"c","content_type":"text/x-c","file_size":"126","description":null,"visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T09:37:48.766+02:00","created_at":"2022-11-21T09:37:48.767+02:00","updated_at":"2022-11-21T09:37:48.767+02:00","children":[]},{"id":"7","user_id":"1479","folder_id":null,"is_folder":false,"folder_name":null,"unique_filename":"drives/users/user_drive_1479/FSix4WZx0s9ey89x3foLxmaC1wCHTSw1HQi8fDxQ32bYQyKmyPJBcgeI33KOrdPfAcOChvkBnIBizj5IQbggeprCpz.cpp","original_filename":"sample1.cpp","file_extension":"cpp","content_type":"text/x-c","file_size":"94","description":null,"visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T09:37:52.324+02:00","created_at":"2022-11-21T09:37:52.324+02:00","updated_at":"2022-11-21T09:37:52.324+02:00","children":[]},{"id":"37","user_id":"1479","folder_id":"36","is_folder":true,"folder_name":"folder 37","unique_filename":null,"original_filename":null,"file_extension":null,"content_type":null,"file_size":null,"description":"People","visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T21:38:30.690+02:00","created_at":"2022-11-21T21:38:30.690+02:00","updated_at":"2022-11-21T21:38:30.690+02:00","children":[]}];

const ids = collectNodeValues(input, 'id');
console.log(ids); // ["3", "36", "37", "42", "5", "7", "37"]

Compiled JS from the TS Playground:

"use strict";
function collectNodeValues(nodeList, targetProperty) {
    const stack = [...nodeList];
    const values = [];
    while (stack.length > 0) {
        const node = stack.shift();
        values.push(node[targetProperty]);
        if (!Array.isArray(node.children))
            continue;
        stack.unshift(...node.children);
    }
    return values;
}
const input = [{ "id": "3", "user_id": "1479", "folder_id": "2", "is_folder": true, "folder_name": "folder 3", "unique_filename": null, "original_filename": null, "file_extension": null, "content_type": null, "file_size": null, "description": "People", "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T09:34:48.546+02:00", "created_at": "2022-11-21T09:34:48.546+02:00", "updated_at": "2022-11-21T09:34:48.546+02:00", "children": [{ "id": "36", "user_id": "1479", "folder_id": "3", "is_folder": true, "folder_name": "folder 4", "unique_filename": null, "original_filename": null, "file_extension": null, "content_type": null, "file_size": null, "description": "People", "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T21:33:48.767+02:00", "created_at": "2022-11-21T21:33:48.767+02:00", "updated_at": "2022-11-21T21:33:48.767+02:00", "children": [{ "id": "37", "user_id": "1479", "folder_id": "36", "is_folder": true, "folder_name": "folder 37", "unique_filename": null, "original_filename": null, "file_extension": null, "content_type": null, "file_size": null, "description": "People", "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T21:38:30.690+02:00", "created_at": "2022-11-21T21:38:30.690+02:00", "updated_at": "2022-11-21T21:38:30.690+02:00", "children": [] }] }, { "id": "42", "user_id": "1479", "folder_id": "3", "is_folder": true, "folder_name": "folder 41", "unique_filename": null, "original_filename": null, "file_extension": null, "content_type": null, "file_size": null, "description": "People", "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T23:38:31.935+02:00", "created_at": "2022-11-21T23:38:31.935+02:00", "updated_at": "2022-11-21T23:38:31.935+02:00", "children": [] }] }, { "id": "5", "user_id": "1479", "folder_id": null, "is_folder": false, "folder_name": null, "unique_filename": "drives/users/user_drive_1479/YTHGg4dnzn8O5a4DGHbntsrKhY2n4ycc3hZG5j7YxdIb5yEka9iToJDi9WxQPe4taSjLP53b1s01mctIy69o7m6L92.c", "original_filename": "sample3.c", "file_extension": "c", "content_type": "text/x-c", "file_size": "126", "description": null, "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T09:37:48.766+02:00", "created_at": "2022-11-21T09:37:48.767+02:00", "updated_at": "2022-11-21T09:37:48.767+02:00", "children": [] }, { "id": "7", "user_id": "1479", "folder_id": null, "is_folder": false, "folder_name": null, "unique_filename": "drives/users/user_drive_1479/FSix4WZx0s9ey89x3foLxmaC1wCHTSw1HQi8fDxQ32bYQyKmyPJBcgeI33KOrdPfAcOChvkBnIBizj5IQbggeprCpz.cpp", "original_filename": "sample1.cpp", "file_extension": "cpp", "content_type": "text/x-c", "file_size": "94", "description": null, "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T09:37:52.324+02:00", "created_at": "2022-11-21T09:37:52.324+02:00", "updated_at": "2022-11-21T09:37:52.324+02:00", "children": [] }, { "id": "37", "user_id": "1479", "folder_id": "36", "is_folder": true, "folder_name": "folder 37", "unique_filename": null, "original_filename": null, "file_extension": null, "content_type": null, "file_size": null, "description": "People", "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T21:38:30.690+02:00", "created_at": "2022-11-21T21:38:30.690+02:00", "updated_at": "2022-11-21T21:38:30.690+02:00", "children": [] }];
const ids = collectNodeValues(input, 'id');
console.log(ids); // ["3", "36", "37", "42", "5", "7", "37"]

Leave a Reply