1

I am trying to dynamically form a nested tree object something like below using JavaScript, can someone please let me know the best way to achieve this?

 var contextpath= {
        text: "TreeRoot",
        items: [ {
            text: "subgroup1" ,
            items: [ {
                text: "subgroup2",
                items: [ {
                    text: "subgroup3",
                    items: [ {
                        text: "subgroup4",
                        items: [ {
                            text: "subgroup5"
                        }]
                    }]
                }]
            }]
        }]
    };

I have delimited string that I am trying to convert to object (that can be used as dat source for tree component).

var path="TreeRoot|subgroup1|subgroup2";

Trying to implement something like below but with recursion / looping using less number of variables.

    var contextpathText= {};
    contextpathText.text ="TreeRoot";

    var childObject={};
    var items=[];
    childObject.text ="subgroup1";
    items.push(childObject);
    contextpathText.items=(items);
5
  • 1
    Looks like you did OK. whathaveyoutried.com Commented Dec 11, 2012 at 22:59
  • What exactly do you want to achieve? Create this object? What are the parameters? Do you have an array you want to transform to this, you just want to create an n deep object like this, or what? Commented Dec 11, 2012 at 23:02
  • subgroup2 is a subgroup of subgroup1? Commented Dec 11, 2012 at 23:10
  • Yes, subgroup2 is a subgroup of subgroup1. (ie. subgroup1 is the parent of subgroup2) Commented Dec 11, 2012 at 23:11
  • You're going to need either more than one string (bad idea), or more than one delimiter (good idea), to define when you are going deeper into the tree, and when you are coming out of that pocket, and back into its parent (or next-child). Commented Dec 11, 2012 at 23:19

2 Answers 2

2

You need a depth counter and to store the current levels of the object you're working with.

var obj = {text:''}, parent, child, i = 0;
obj.text = 'TreeRoot';
parent = obj;
while (++i <= 5) {
    if (parent.items === undefined) parent.items = []; // because you don't have an items on the last subgroup you can't put it in the object literal
    child = {text: 'subgroup'+i};
    parent.items.push(child);
    parent = child;
}
parent = child = null; // cleanup
obj;

jsbeautified JSON.stringify(obj) is now

{
    "text": "TreeRoot",
    "items": [{
        "text": "subgroup1",
        "items": [{
            "text": "subgroup2",
            "items": [{
                "text": "subgroup3",
                "items": [{
                    "text": "subgroup4",
                    "items": [{
                        "text": "subgroup5"
                    }]
                }]
            }]
        }]
    }]
}

Edit For delimited string

var path = 'TreeRoot|subgroup1|subgroup2';

var obj = {text:''}, parent, child, levelText = path.split('|').reverse();
obj.text = levelText.pop() || '';
parent = obj;
while (levelText.length > 0) {
    child = {text: levelText.pop()};
    if (!parent.items) parent.items = [];
    parent.items.push(child);
    parent = child;
}
obj;
Sign up to request clarification or add additional context in comments.

Comments

1

Beat me to it, but I went with this code:

var contextpath = { text: "TreeRoot", items: []}

var items = contextpath.items;

for(var i = 1; i <= 5; i++) {
    items.push({ text: "subgroup" + i, items: []});
    items = items[0].items;
}

The parent & child nomenclature is definitely clearer, for this sort of thing, but I wanted to show that you didn't have to declare the new object as a variable first, you can just push the object literal.

Whoops, just now noticed that you don't have an items array in your desired structure. My code creates the spare, so you end up with

// snip
                text: "subgroup4",
                    items: [ {
                        text: "subgroup5",
                        items: []
                    }]
// etc.

1 Comment

You're very welcome, but Paul S.'s answer more closely matches what you asked for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.