Skip to content

Instantly share code, notes, and snippets.

@alonronin
Last active August 26, 2023 09:23
Show Gist options
  • Star 34 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • 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": []
// }
// ]
// }
//]
@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/lodash@4.17.20/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