【问题标题】:create javascript tree out of list of objects从对象列表中创建 javascript 树
【发布时间】:2015-07-09 12:51:53
【问题描述】:

我想将对象列表“翻译”成 jstree 可食用的 json 格式:

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

我的输入如下所示:

[
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
,
...]

嗯,老实说,这不是一棵树,而是一片森林。不过没关系。

我花了很多时间在它上面,但没有让它工作。在 javascript 中对数组进行操作似乎很讨厌(与 Java、C++ 或 PHP 相比)...

到目前为止我尝试过的是:

  1. (pre)源数据(对象列表)满足一个条件:儿子不能在其父之前出现
  2. 使其成为关联数组(key=id, value=object),因此它必须是字符串键控。
  3. 弹出最后一个数组元素并将其推入其父元素的子数组中。对所有非 null 父元素重复此操作。
  4. 希望这能奏效。

【问题讨论】:

  • 请发布您到目前为止所尝试的内容。这可能会让我们更容易为您提供帮助。
  • 我发现 PHP 数组比 JavaScript 数组更糟糕。 JS 非常精简。你想做什么,什么不起作用,我不太明白......
  • 我已经编辑了我的帖子并描述了算法思想。我知道我应该在 stacoverflow 上写到目前为止我尝试过的东西 - 但我没有 JS 经验,而且我的代码看起来很丑,以至于将它粘贴在这里毫无意义:/...

标签: javascript tree


【解决方案1】:

您需要首先将所有项目放入一个由其 ID 索引的稀疏数组中,然后翻译除子项(应该存在但为空)和包括父项 ID 之外的所有内容:

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

然后你会想要遍历所有的项目,将孩子添加到他们的父母中:

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

然后找到根:

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

然后通过删除父 ID 来清理项目:

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

树的根将在roots


您的方法不起作用的原因是,如果任何子元素的父元素的 ID 号更大,则父元素将不存在;您已经处理并弹出它。在完成之前,您必须保留数组中的所有项目。

【讨论】:

  • 为简单起见,我使用了许多在旧浏览器中可能不可用的数组方法。这些方法可以安全地填充或修改代码以不使用这些方法。
  • 好吧,我试过你的算法,但我不喜欢JS将undefined插入到数组中的“洞”中(实际上,我想要一个中间阶段的典型地图结构)。所以我决定创建一个字符串键数组。
  • @tkoomzaaskz:它不是特定于数组的。访问对象上不存在的属性会产生undefined。此外,所有对象(包括数组)的属性都是字符串键控的;只是数组的属性是数字的字符串表示形式。 (当您使用整数 b 执行 a[b] 时,它会被强制转换为字符串。)
  • 也许我的 chrome javascript 控制台让我认为该数组与实际不同(这让我认为它用未定义填充了漏洞)。无论如何,非常感谢!
  • @tkoomzaaskz:嗯,确实如此;这些孔不一定在内存中表示,但它们可能是。没关系,因为如果明确设置为undefined,则为undefined,如果未明确定义,则设置为undefined
【解决方案2】:

也许unsplay 能解决问题?

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

(免责声明:我是作者)

【讨论】:

    猜你喜欢
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 2020-10-25
    相关资源
    最近更新 更多