admin管理员组

文章数量:1277377

I would like to 'translate' a list of objects into a json format edible by jstree:

data = [
    { 
        "data" : { 
            "title" : "father",
            "attr" : { "href" : "#" }
        },
        "children" : [
            { 
                "data" : { 
                    "title" : "Older Son",
                    "attr" : { "href" : "#" }
                },
                "children" : []
            },
            { 
                "data" : { 
                    "title" : "Younger Son",
                    "attr" : { "href" : "#" }
                },
                "children" : []
            }
        ]
    },
]

My input looks like this:

[
Object
id: 35
name: "bnm,bnm"
parent_id: null
, 
Object
id: 36
name: "ghk"
parent_id: 35
, 
Object
id: 37
name: "hgkgh"
parent_id: null
, 
Object
id: 38
name: "jklhjk"
parent_id: null
, 
Object
id: 39
name: "fghdfgh"
parent_id: 38
, 
Object
id: 40
name: "bsdbd"
parent_id: 38
,
...]

Well, to be honest, this would not be a tree, rather a forest. But it doesn't matter.

I've spent quite a lot of time on it, but failed to get it working. Operating on arrays seems to be nasty in javascript (in parison to Java,C++ or PHP)...

What I've tried so far is:

  1. (pre) the source data (list of objects) meet one condition: a son can't be present before it's parent
  2. make it associative array (key=id, value=object), so it had to be string-keyed.
  3. pop last array element and push it inside its parent element's children array. Repeat this for all non-null-parent elements.
  4. hoped this should work.

I would like to 'translate' a list of objects into a json format edible by jstree:

data = [
    { 
        "data" : { 
            "title" : "father",
            "attr" : { "href" : "#" }
        },
        "children" : [
            { 
                "data" : { 
                    "title" : "Older Son",
                    "attr" : { "href" : "#" }
                },
                "children" : []
            },
            { 
                "data" : { 
                    "title" : "Younger Son",
                    "attr" : { "href" : "#" }
                },
                "children" : []
            }
        ]
    },
]

My input looks like this:

[
Object
id: 35
name: "bnm,bnm"
parent_id: null
, 
Object
id: 36
name: "ghk"
parent_id: 35
, 
Object
id: 37
name: "hgkgh"
parent_id: null
, 
Object
id: 38
name: "jklhjk"
parent_id: null
, 
Object
id: 39
name: "fghdfgh"
parent_id: 38
, 
Object
id: 40
name: "bsdbd"
parent_id: 38
,
...]

Well, to be honest, this would not be a tree, rather a forest. But it doesn't matter.

I've spent quite a lot of time on it, but failed to get it working. Operating on arrays seems to be nasty in javascript (in parison to Java,C++ or PHP)...

What I've tried so far is:

  1. (pre) the source data (list of objects) meet one condition: a son can't be present before it's parent
  2. make it associative array (key=id, value=object), so it had to be string-keyed.
  3. pop last array element and push it inside its parent element's children array. Repeat this for all non-null-parent elements.
  4. hoped this should work.
Share Improve this question edited Mar 30, 2013 at 1:33 ducin asked Mar 30, 2013 at 1:25 ducinducin 26.5k44 gold badges166 silver badges261 bronze badges 3
  • Please post what you have tried so far. It might make it easier for us to help you. – Felix Kling Commented Mar 30, 2013 at 1:26
  • I find PHP arrays nastier than JavaScript arrays. JS is very lean. What are you trying to do and what didn't work, I don't quite get it... – elclanrs Commented Mar 30, 2013 at 1:27
  • I've edited my post and described the algorithm idea. I know I should write on stacoverflow what I've tried so far -but I'm not experienced in JS and my code looked so ugly that it could make no sense to paste it here :/... – ducin Commented Mar 30, 2013 at 1:38
Add a ment  | 

2 Answers 2

Reset to default 9

You'll want to first put all of your items into a sparse array indexed by their ID and translate everything except the children (which should be present but empty) and including the parent ID:

var itemsByID = [];
items.forEach(function(item) {
    itemsByID[item.id] = {
        data: {title: item.name},
        children: [],
        parentID: item.parent_id
    };
});

Then you'll want to go through all of the items, adding children to their parents:

itemsByID.forEach(function(item) {
    if(item.parentID !== null) {
        itemsByID[item.parentID].children.push(item);
    }
});

Then find the roots:

var roots = itemsByID.filter(function(item) { return item.parentID === null; });

Then clean the items up by removing the parent ID:

itemsByID.forEach(function(item) { delete item.parentID; });

The roots of the tree will be in roots.


The reason your method didn't work is that if any children have a parent with a greater ID number, the parent element will not exist; you have already processed and popped it. You must leave all items in the array until you're done.

Maybe unsplay does the trick?

>> var unsplay = require('unsplay');
>> unsplay([{id: 0}, {id: 1, pid: 0}], 'id', 'pid');
[{
  item: {id: 0},
  children: [{
    item: {id: 1, pid: 0},
    children: []
  }]
}]

(DISCLAIMER: I am the author)

本文标签: create javascript tree out of list of objectsStack Overflow