Skip to content

Instantly share code, notes, and snippets.

@alonronin
Last active August 26, 2023 09:23
Show Gist options
  • Save alonronin/2592a6a81db67804db1f to your computer and use it in GitHub Desktop.
Save alonronin/2592a6a81db67804db1f to your computer and use it in GitHub Desktop.
Create recursive tree from json using lodash transform without recursion. Can have unlimited nesting.
var _ = require('lodash');
var arr = [
{"name":"my2child1","title":"My 2 Child 1","parent":"my2"},
{"name":"my2child2","title":"My 2 Child 2","parent":"my2"},
{"name":"parent","title":"A single parent"},
{"name":"child-parent","title":"A child parent","parent":"child1"},
{"name":"my","title":"My"},
{"name":"my2","title":"My2"},
{"name":"child1","title":"Child 1","parent":"my"},
{"name":"child2","title":"Child 2","parent":"my"}
];
var result = _.filter(arr, function(item){
var parentName = item.parent;
item.children = this(item.name);
return !(parentName && this(parentName).push(item));
}, _.memoize(function(){ return []; }));
console.log(JSON.stringify(result, null, 2));
// ==> output
//[
// {
// "name": "parent",
// "title": "A single parent",
// "children": []
// },
// {
// "name": "my",
// "title": "My",
// "children": [
// {
// "name": "child1",
// "title": "Child 1",
// "parent": "my",
// "children": [
// {
// "name": "child-parent",
// "title": "A child parent",
// "parent": "child1",
// "children": []
// }
// ]
// },
// {
// "name": "child2",
// "title": "Child 2",
// "parent": "my",
// "children": []
// }
// ]
// },
// {
// "name": "my2",
// "title": "My2",
// "children": [
// {
// "name": "my2child1",
// "title": "My 2 Child 1",
// "parent": "my2",
// "children": []
// },
// {
// "name": "my2child2",
// "title": "My 2 Child 2",
// "parent": "my2",
// "children": []
// }
// ]
// }
//]
@alonronin
Copy link
Author

update it to be more functional using one iteration inspired by Tal Weinfeld.

@alonronin
Copy link
Author

update to be even more functional, thanx Tal 😄

@yogendra9891
Copy link

[
{
"name": "parent",
"title": "A single parent",
"children": []
},
{
"name": "my",
"title": "My",
"children": [
{
"name": "child1",
"title": "Child 1",
"parent": "my",
"children": [
{
"name": "child-parent",
"title": "A child parent",
"parent": "child1",
"children": []
}
]
},
{
"name": "child2",
"title": "Child 2",
"parent": "my",
"children": []
}
]
},
{
"name": "my2",
"title": "My2",
"children": [
{
"name": "my2child1",
"title": "My 2 Child 1",
"parent": "my2",
"children": []
},
{
"name": "my2child2",
"title": "My 2 Child 2",
"parent": "my2",
"children": []
}
]
}
]

this is my json

I need all parents name of a each node.

@MrEldin
Copy link

MrEldin commented Jul 4, 2018

Hi @alonronin, i tried this one, and I got error:

"this is not a function"

What I'm doing wrong?

@alonronin
Copy link
Author

@MrEldin it was with lodash 3, need to refactor to 4 remove the this or use bind.

@samvirkar144
Copy link

Hi @alonronin, @MrEldin ,Is there any external library or npm package that can handle very large files (Millions json object in array) by passing specific column. Thank you...

@tanveerbyn
Copy link

@LFTroya
Copy link

LFTroya commented Jul 29, 2019

_.defaults

I think you could replace _.defaults with Object.assign() and remove lodash dependency

@stzach
Copy link

stzach commented Feb 19, 2021

Hello,

Looking to enhance your functionality with ordering and also create the opposite tree2recursive function.

var arr = [
{ id: "0", title: "ROOT", parentId: "", order: 1 },
{ id: "30", title: "My 2 Child 1", parentId: "3", order: 2 },
{ id: "31", title: "My 2 Child 2", parentId: "3", order: 1 },
{ id: "1", title: "A single parent", parentId: "0", order: 3 },
{ id: "200", title: "A child parent", parentId: "20", order: 1 },
{ id: "2", title: "My", parentId: "0", order: 1 },
{ id: "3", title: "My2", parentId: "0", order: 2 },
{ id: "20", title: "Child 1", parentId: "2", order: 2 },
{ id: "21", title: "Child 2", parentId: "2", order: 1 }
];

So the arr item is having order so all items are order in the tree children property. Also maybe there is a ROOT element, but this is not important as you can easily add it later on. Any thoughts on that?

@amirshnll
Copy link

amirshnll commented Jun 23, 2022

First, you need install loash with below command with npm:

npm i lodash

Second, you must import _ from loash

import _ from "lodash";

Finally, run this function:

export const recursive_lists = (data) => {
  const grouped = _.groupBy(data, (item) => item. parent_id);

  function childrenOf(parent_id) {
    return (grouped[parent_id] || []).map((item) => ({
      id: item.id,
      title: item.title,
      child: childrenOf(item.id),
    }));
  }

  return childrenOf(null);
};

or

First:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

Second:

function recursive_lists(data) {
  const grouped = _.groupBy(data, (item) => item.parent_id);

  function childrenOf(parent_id) {
    return (grouped[parent_id] || []).map((item) => ({
      id: item.id,
      title: item.title,
      child: childrenOf(item.id),
    }));
  }

  return childrenOf(null);
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment