Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
262 views
in Technique[技术] by (71.8m points)

javascript - What are the best ways to reference branches of a JSON tree structure?

So I've got a JSON file that gets parsed into an object in Javascript. I know what you're thinking: lucky guy. The JSON is essentially a flow diagram in a big tree form. Here's tiny a sample of what I'm trying to achieve:

tree = {
    "options": [
        {
            "options": [
                {
                    "name": "target",
                },
            ],
        },
        {
            "options": [
                {
                    "link": "...?",
                },
            ],
        },
    ]
}

So in this example, I'll be deep in the second branch (where it says "link") and I'll want to be able to jump to the branch that contains "name": "target". This is JSON remember so it'll need to be a string (unless there's a native for linking?! is there?) but I don't know how best to format that.

As I see it, I've got at least a couple of options.

  1. I could search. If name was unique, I could scale the tree looking for elements until I found it. I've never done with with Javascript before but I expect it to be slow.

  2. I could use a navigation path like options:1:options:1 that describes each key for the path. Again, I've never done this but, assuming there are no errors, it would be a lot faster. How would you implement it?

Are there any other options available to me? What seems best? Is there a way to unpack this when JSON decoding, or is that a recipe for an infinite loop?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

What about link: 'tree.options[0].options[0]' then eval(path.to.link)?

Following samples were tested with Chrome only. Same tree for all :

var tree = { level1: [{ key: 'value' }] };

No eval

function resolve(root, link) {
    return (new Function('root', 'return root.' + link + ';'))(root);
}

var value = resolve(tree, path.to.link);

Fallback to window

function resolve(root, link) {
    return (new Function(
        'root', 'return root.' + (link || root) + ';'
    ))(link ? root : window);
}

resolve(tree, 'level1[0].key'); // "value"
resolve('tree.level1[0].key'); // "value"

Catching errors

The try/catch block prevents broken links from throwing errors.

function resolve(root, path) {
    try {
        return (new Function('root', 'return root.' + path + ';'))(root);
    } catch (e) {}
}

resolve(tree, 'level1[0].key'); // "value"
resolve(tree, 'level1[1].key'); // undefined

Using custom path format

The good part here is that we can pass either an object or an array as root. Also note that we can replace the slash in path.split('/') with any char of our choice.

function resolve(root, path) {
    path = '["' + path.split('/').join('"]["') + '"]';
    return (new Function('root', 'return root' + path + ';'))(root);
}

resolve(tree.level1, '0/key'); // "value"
resolve(tree, 'level1/0/key'); // "value"
resolve(tree, 'level1/0'); // Object {key: "value"}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...