引用 JSON 树结构的分支的最佳方法是啥?

Posted

技术标签:

【中文标题】引用 JSON 树结构的分支的最佳方法是啥?【英文标题】:What are the best ways to reference branches of a JSON tree structure?引用 JSON 树结构的分支的最佳方法是什么? 【发布时间】:2013-08-22 13:02:01 【问题描述】:

所以我有一个 JSON 文件,它被解析为 javascript 中的对象。我知道你在想什么:幸运的家伙。 JSON本质上是一个大树形式的流程图。这是我要实现的目标的一小部分示例:

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

因此,在本例中,我将深入第二个分支(其中显示为"link"),并且我希望能够跳转到包含"name": "target" 的分支。记住这是 JSON,所以它需要是一个字符串(除非有一个用于链接的本机?!有吗?)但我不知道如何最好地格式化它。

在我看来,我至少有几个选择。

    我可以搜索。如果name 是唯一的,我可以缩放树以查找元素,直到找到它。我以前从未使用过 Javascript,但我预计它会很慢。

    我可以使用像options:1:options:1 这样的导航路径来描述路径的每个键。同样,我从来没有这样做过,但是假设没有错误,它会快很多。你将如何实现它?

我还有其他选择吗?什么看起来最好?有没有办法在 JSON 解码时解包,或者这是一个无限循环的秘诀?

【问题讨论】:

不清楚“解析dict对象”是什么意思。 尝试并找到一个新项目。哈哈。你肯定有泡菜。这似乎是您开发自己的功能的案例,该功能将树枝一根一根地撕下然后对它们起作用。它是 JSON,所以我不知道“速度”实际上会成为一个因素。 @Pointy 我不知道如何更好地表达它。我想“获取”包含名称/值对"name":"target" 的对象。原谅我,我是一个 Pythonista,谈论 Javascript,所以我肯定会理解一些不正确的术语。 【参考方案1】:

link: 'tree.options[0].options[0]' 然后eval(path.to.link) 呢?

以下示例仅使用 Chrome 进行了测试。所有人的同一棵树:

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

没有eval

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


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

回退到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"

捕捉错误

try/catch 块可防止断开的链接引发错误。

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

使用自定义路径格式

这里的好处是我们可以将对象或数组作为root 传递。另请注意,我们可以将path.split('/') 中的斜杠替换为我们选择的任何字符。

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"

【讨论】:

这当然很有趣...大大简化了事物的编码方面,安全性在这里并不是真正的问题,因为我控制着整个事物。 没有-eval 的版本绝对应该安抚那些足够在意的人,但除了 eval 的任意安全风险之外,一种方法相对于另一种方法的优势是什么? 我认为你的情况没有。我想说您可以更好地控制路径的来源,例如,您可以将树的副本传递给 resolve : resolve(treeCopy, path.to.link) @downvoter 我猜你对动态代码评估投了反对票。恐惧!恐惧!好吧,只要您保持对输入的控制,这不一定是邪恶的:nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood. 动态代码评估的替代方法可以在这里找到:***.com/q/6491463/1636522。

以上是关于引用 JSON 树结构的分支的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Java数据结构——2-3树

决策树是啥东东?

存储树结构的集合是啥?

反序列化json树结构并设置父项

sklearn库学习----决策树(分类树DecisionTreeClassifier)

使用 mptt 在 Python / Django 中创建 JSON 以反映树结构的最快方法