Fix: Js Recursive Function to Get the Nested (Multilevel) Child Objects as Array of Objects

Fix: JS recursive function to get the nested (multilevel) child objects as array of objects

const myObj = {        parent1: {            child1: {                lastChild1: { test: 'cool'}            },            child2: {                lastChild2: { test: 'cool'}            }        },        parent2: {            child2_1: {                lastChild2_1: { test: 'cool'}            },            child2_2: {                lastChild2_2: { test: 'cool'}            }        }    }

function getOptions(obj) { return Object.keys(obj).reduce((acc, cur) => { acc.push({ id: cur, label: cur, children: recurseList(obj[cur]) }) return acc; }, [])} function recurseList(obj) { return Object.keys(obj).reduce((acc, cur) => { if(obj[cur] instanceof Object) { let data = { id: cur, label:cur } const children = recurseList(obj[cur]); If(children.length) { data.children = children } acc.push(data) } return acc; }, [])}
var result = getOptions(myObj)console.log('result', result)

Search nested array of objects and return full parents as results in JavaScript

You could take a recursive approach and check if the nested arrays have the wanted name.

function searchPages(array, string) {    const find = ({ name, pages }) => name.includes(string) || pages && pages.some(find);    return array.filter(find);}
const data = [{ name: '1', pages: [{ name: '1.1', pages: [] }, { name: '1.2', pages: [] }] }, { name: '2', pages: [] }, { name: '3', pages: [] }], searchResults = searchPages(data, '1.1');
console.log(searchResults);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Recursively searching a nested array in JS

There's an error in your code, at the moment you're just recursing on a single branch of the three, you're not recursing across the whole data structure, infact if you're trying to search for "node_modules" your code returns undefined.

Try to apply this tiny modification to your code

const data = [    {        "type": "directory",        "name": "/home/user/test-tree",        "contents": [            {                "type": "directory",                "name": "my-folder",                "contents": [                    {                        "type": "directory",                        "name": "nested-folder",                        "contents": []                    }                ]            },            {                "type": "directory",                "name": "node_modules",                "contents": [                    {                        "type": "directory",                        "name": "gunzip-file",                        "contents": []                    }                ]            }        ]    }];
function treeSearch(array, dirName) { for (let i = 0; i < array.length; i++) { if (array[i].name === dirName) { return array[i]; } else if (array[i].contents && array[i].contents.length) { const result = treeSearch(array[i].contents, dirName); // return the result only if it's actually found otherwise keep looping if(result) return result; } }}
console.log(treeSearch(data, "node_modules"));

Recursively filter array of objects

Using .filter() and making a recursive call as I described in the comment above is basically what you need. You just need to update each .children property with the result of the recursive call before returning.

The return value is just the .length of the resulting .children collection, so if there's at least one, the object is kept.

var res = input.filter(function f(o) {
if (o.value.includes("Hit")) return true

if (o.children) {
return (o.children = o.children.filter(f)).length
}
})

const input = [  {    value: 'Miss1',    children: [      { value: 'Miss2' },      { value: 'Hit1', children: [ { value: 'Miss3' } ] }    ]  },  {    value: 'Miss4',    children: [      { value: 'Miss5' },      { value: 'Miss6', children: [ { value: 'Hit2' } ] }    ]  },  {    value: 'Miss7',    children: [      { value: 'Miss8' },      { value: 'Miss9', children: [ { value: 'Miss10' } ] }    ]  },  {    value: 'Hit3',    children: [      { value: 'Miss11' },      { value: 'Miss12', children: [ { value: 'Miss13' } ] }    ]  },  {    value: 'Miss14',    children: [      { value: 'Hit4' },      { value: 'Miss15', children: [ { value: 'Miss16' } ] }    ]  },];
var res = input.filter(function f(o) { if (o.value.includes("Hit")) return true
if (o.children) { return (o.children = o.children.filter(f)).length }})console.log(JSON.stringify(res, null, 2))

Javascript - Convert Nested Object to Array of items

You could take an iterative and recursive approach by checking header keeping the corresponding divider and iterate children.

Then you need to add the standard object for any item.

The recursive callback uses a closure over the group. if not set, the group is a root item.

function getParts(array) {    var result = [];    array.forEach(function iter(group) {        return function ({ id, name, children }, i, { length }) {            if (!group && children.length) {                result.push({ header: name });            }            if (group || !children.length) {                result.push({ name, group: group || name, id });            }            children.forEach(iter(name));            if (!group && i + 1 !== length) {                result.push({ divider: true });            }        };    }(''));    return result;}
var data = [{ id: 1, name: "Electronics", path: "Electronics", children: [{ id: 2, name: "Laptops & PC", path: "Electronics > Laptops & PC", children: [] }, { id: 7, name: "Phones & Accessories", path: "Electronics > Phones & Accessories", children: [{ id: 8, name: "Smartphones", path: "Electronics > Phones & Accessories > Smartphones", children: [{ id: 9, name: "Android", path: "Electronics > Phones & Accessories > Smartphones > Android", children: [] }, { id: 10, name: "iOS", path: "Electronics > Phones & Accessories > Smartphones > iOS", children: [] }] }] }] }, { id: 11, name: "Software", path: "Software", children: [] }, { id: 11, name: "Software", path: "Software", children: [] }, { id: 11, name: "Software", path: "Software", children: [] }], result = getParts(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Flatten a deeply nested data structure of arrays, objects + strings into a list of data items while mapping the former parent-child relationship too

First of all, I would not be answering if there was not already a good answer. Please, on StackOverflow, always show your own attempts and explain where you got stuck. But since there is already an answer, I think this version might be a bit simpler.

Second, I'm assuming this output format is some sort of directed graph, that the first half is your list of vertices and the second half a list of edges. If so I don't know if your output format is constrained here. But if you had the option, I would think a better structure would be an object with vertices and edges properties, each containing an array. You might then not need the edges' ids. And the code could also be simplified.

This version first converts to an intermediate structure like this:

[
{id: "1", data: {label: {author: "John Doe", age: 26}}, children: [
{id: "2", data: {label: "books"}, children: [
{id: "3", data: {label: {title: "Book 1"}}, children: []},
{id: "4", data: {label: {title: "Book 2"}}, children: [
{id: "5", data: {label: "chapters"}, children: [
{id: "6", data: {label: {title: "No Way Home"}}, children: []}
]}
]}
]}
]}
]

Then we flatten that structure into the first section of the output and use it to calculate the relationships (edges?) between nested nodes to go in the second section.

The code looks like this:

const transform = (input) => {
const extract = (os, nextId = ((id) => () => String (++ id)) (0)) => os .map ((o) => ({
id: nextId(),
data: {label: Object .fromEntries (Object .entries (o) .filter (([k, v]) => !Array .isArray (v)))},
children: Object .entries (o) .filter (([k, v]) => Array .isArray (v)) .flatMap (([k, v]) => [
{id: nextId(), data: {label: k}, children: extract (v, nextId)},
])
}))

const relationships = (xs) =>
xs .flatMap (({id: target, children = []}) => [
... children .map (({id: source}) => ({id: `e${source}-${target}`, source, target})),
... relationships (children),
])

const flatten = (xs) =>
xs .flatMap (({children, ...rest}) => [rest, ... flatten (children)])

const res = extract (input)

return [...flatten (res), ... relationships (res)]
}

const input = [{author: "John Doe", age : 26, books: [{title: "Book 1"}, {title: "Book 2", chapters: [{title: "No Way Home", page: 256}]}]}]

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

javascript find child object in nested arrays

Caveat: This uses a couple of Array.prototype functions that were only added in ECMAScript 5 and thus will not work with older browsers unless you polyfill them.

You can loop over all first-level objects in your array, and then filter the categories based on your condition and collect all matches in an array. Your final result will be the first element in the array of matches (no match found if array is empty).

var matches = [];
var needle = 100; // what to look for

arr.forEach(function(e) {
matches = matches.concat(e.Categories.filter(function(c) {
return (c.Id === needle);
}));
});

console.log(matches[0] || "Not found");

JSFiddle: http://jsfiddle.net/b7ktf/1/

References:

Array.prototype.forEach

Array.prototype.concat

Array.prototype.filter

JS Recursive Nested JSON Array Children Join Key

You can use a a recursive approach, say, creating a function getPaths that will get a list of paths using a property key as an input.

In this case we'll use 'NAME', and build up an array of the relevant paths.

let input = [ { "PRODUCT_CATEGORY_ID": "1", "NAME": "OTOMOBİL PARÇALARI", "DESCRIPTION": "Araba Parçaları", "ACTIVE": "True", "PARENT_PRODUCT_CATEGORY_ID": "", "children": [ { "PRODUCT_CATEGORY_ID": "3", "NAME": "HONDA PARÇALARI", "DESCRIPTION": "Honda Parçaları", "ACTIVE": "True", "PARENT_PRODUCT_CATEGORY_ID": "1" }, { "PRODUCT_CATEGORY_ID": "4", "NAME": "RENAULT PARÇALARI", "DESCRIPTION": "Renault Parçaları", "ACTIVE": "True", "PARENT_PRODUCT_CATEGORY_ID": "1", "children": [ { "PRODUCT_CATEGORY_ID": "5", "NAME": "MINIMAL RENAULT PARÇALARI", "DESCRIPTION": "", "ACTIVE": "True", "PARENT_PRODUCT_CATEGORY_ID": "4" } ] } ] } ]

function getPaths(obj, property, path = '') {
const paths = [];
for(let k in obj) {
if (typeof(obj[k]) === 'object') {
paths.push(...getPaths(obj[k], property, path));
} else if (k === property) {
path += (path ? ' > ' : '') + obj[k];
paths.push(path)
}
}
return paths;
}

console.log('Paths:', getPaths(input, 'NAME'))

Create nested JSX list items from multi-level nested array of objects reactjs

You can "render" your children into a variable and use this directly in your component.
The trick then is to use a recursive component. That way it doesn‘t matter how deep your tree is. You don‘t need to edit this component if your tree gets deeper.

Here is how that might look like:

function ListItem({ item }) {
let children = null;
if (item.values) {
children = (
<ul>
{item.values.map(i => <ListItem item={i} key={i.id} />)}
</ul>
);
}

return (
<li>
{item.name}
{children}
</li>
);
}

Here is a working example on Codesandbox with your data.



Related Topics



Leave a reply



Submit