4

Any suggestions for how to recursively create a set of nested arrays / objects?

I am letting my users add multiple elements using a quick textarea. They will indicate sub items with an asterisk. So I have a string like this that I want to turn into an array.

level 1.1
level 1.2
* level 1.2.1
** level 1.2.1.1
** level 1.2.1.2
* level 1.2.2

This is the result I would like to see:

[
    {
        name: "level 1.1"
    },
    {
        name: "level 1.2",
        nodes: [
            {
                name: "level 1.2.1",
                nodes: [
                    {
                        name: "level 1.2.1.1"
                    },
                    {
                        name: "level 1.2.1.2"
                    }
                ]
            },
            {
                name: "level 1.2.2"
            }
        ]
    }
]

The challenge is that I don't know the depth that the nodes will go down to.

Any suggestions would be gratefully received.

3
  • 4
    ... and what you tried is ??? Commented Nov 27, 2017 at 8:40
  • Homework, ha! Brings back horrible memories from LONG ago. What's happening is that I'm giving people a chance to create multiple items at once through a text area, if they want something to be a nested item then they can add the asterisks. So the input data is as given. Commented Nov 27, 2017 at 8:53
  • @Zagreus Sounds like something that would leave a lot of room for user error. I'd suggest giving your users an interface for building the nested structure. Commented Nov 27, 2017 at 9:38

1 Answer 1

4

This is a linear approach, without recursion.

You could count the stars and take this information for the wanted level of the given node.

This proposal uses an array as reference to the last inserted level and maintains the wanted object structure.

This solution does not provide sanity checks, if a level is missing.

var data = ['level 1.1', 'level 1.2', '* level 1.2.1', '** level 1.2.1.1', '** level 1.2.1.2', '* level 1.2.2'],
    result = [],
    levels = [{ nodes: result }];

data.forEach(function (s) {
    var level = (s.match(/^\*+(?=\slevel)/) || [''])[0].length,
        name = s.match(/[^*]+$/)[0].trim();

    levels[level].nodes = levels[level].nodes || [];
    levels[level].nodes.push(levels[level + 1] = { name: name });
});

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

Sign up to request clarification or add additional context in comments.

1 Comment

That's great thank you. If i understand it, you're using regex to work out how many *s there are. I will throw in a quick validation to make sure that there's no missed levels and I should be good to go.

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.