【问题标题】:JavaScript - Manipulate nested multidimensional array of objectsJavaScript - 操作嵌套的多维对象数组
【发布时间】:2014-02-13 03:34:47
【问题描述】:

我正在使用 D3 创建用户可以操作的树形布局。我有一个对象,其中包含应用程序中其他对象的子数组,让用户选择不同的路径。

我从一个没有 ID 的对象开始,然后使用 D3 循环遍历它们以添加 ID:

    var source = {
    "name": "Top Condition",
    "state": "condition",
    "children": [{
            "name": "Open",
            "dest": "true",
            "state": "open"
    }, {
            "name": "Sub Condition 1",
            "dest": "false",
            "state": "condition",
            "children": [{
                    "name": "Open",
                    "dest": "true",
                    "state": "open"
            }, {
                    "name": "Open",
                    "dest": "false",
                    "state": "open"
            }, {
                    "name": "Open",
                    "dest": "unknown",
                    "state": "open",
                    "children": [{
                            "name": "Open",
                            "dest": "true",
                            "state": "open"
                    }, {
                            "name": "Open",
                            "dest": "false",
                            "state": "open"
                    }, {
                            "name": "Open",
                            "dest": "unknown",
                            "state": "open"
                    }]
            }]
    },{
            "name": "Sub Condition 2",
            "dest": "unknown",
            "state": "condition"
            ,"children": [{
                    "name": "Open",
                    "dest": "true",
                    "state": "open"
            }, {
                    "name": "Open",
                    "dest": "false",
                    "state": "open"
            }, {
                    "name": "Sub Condition 3",
                    "dest": "false",
                    "state": "condition",
                    "children": [{
                            "name": "Open",
                            "dest": "true",
                            "state": "open"
                    }, {
                            "name": "Open",
                            "dest": "false",
                            "state": "open"
                    }, {
                            "name": "Open",
                            "dest": "unknown",
                            "state": "open"
                    }]

            }]
    }]
}




// Compute the new tree layout.
var nodes = tree.nodes(source).reverse(),
        links = tree.links(nodes);

// Update the nodes with IDs
var node = svg.selectAll("g.node")
    .data(nodes, function (d) {
    return d.id || (d.id = ++i);
});

这是我在 D3 完成上面的魔术之后正在使用的对象(ID 是手动添加的,不完全是 D3 生成的):

source = {
    "name": "Top Condition",
    "id": 1,
    "state": "condition",
    "children": [{
            "name": "Open",
            "id": 2,
            "dest": "true",
            "state": "open"
    }, {
            "name": "Sub Condition 1",
            "id": 3,
            "dest": "false",
            "state": "condition",
            "children": [{
                    "name": "Open",
                    "id": 4,
                    "dest": "true",
                    "state": "open"
            }, {
                    "name": "Open",
                    "id": 5,
                    "dest": "false",
                    "state": "open"
            }, {
                    "name": "Open",
                    "id": 6,
                    "dest": "unknown",
                    "state": "open",
                    "children": [{
                            "name": "Open",
                            "id": 14,
                            "dest": "true",
                            "state": "open"
                    }, {
                            "name": "Open",
                            "id": 15,
                            "dest": "false",
                            "state": "open"
                    }, {
                            "name": "Open",
                            "id": 16,
                            "dest": "unknown",
                            "state": "open"
                    }]
            }]
    },{
            "name": "Sub Condition 2",
            "id": 7,
            "dest": "unknown",
            "state": "condition"
            ,"children": [{
                    "name": "Open",
                    "id": 8,
                    "dest": "true",
                    "state": "open"
            }, {
                    "name": "Open",
                    "id": 9,
                    "dest": "false",
                    "state": "open"
            }, {
                    "name": "Sub Condition 3",
                    "id": 10,
                    "dest": "false",
                    "state": "condition",
                    "children": [{
                            "name": "Open",
                            "id": 11,
                            "dest": "true",
                            "state": "open"
                    }, {
                            "name": "Open",
                            "id": 12,
                            "dest": "false",
                            "state": "open"
                    }, {
                            "name": "Open",
                            "id": 13,
                            "dest": "unknown",
                            "state": "open"
                    }]

            }]
    }]
}

所以我想要做的是有一个函数,它接受对象的 ID,然后将“子”数组添加到嵌套在源中某处的对象(或删除子数组)。

例如,对于包含 id: 13 的对象,我想将其添加到对象中:

    var children = [{
        "name": "Open",
        "dest": "true",
        "state": "open"
}, {
        "name": "Open",
        "dest": "false",
        "state": "open"
}, {
        "name": "Open",
        "dest": "unknown",
        "state": "open"
}];

另外,我需要能够做相反的事情并从 ID 10 中删除 children 数组。

然后我将通过 D3 运行它以获取输入的任何节点的 ID 并重新渲染树。

这可能吗?我该如何实现?我愿意使用下划线或其他库,但根据我对文档的理解无法弄清楚如何使用。

【问题讨论】:

  • 让您尝试清除这一点,以根据 ID 找到一个对象并添加一组子对象。这是正确的吗?
  • 没错。我还希望能够找到一个已经有 children 数组的对象并将其删除。

标签: javascript arrays object multidimensional-array d3.js


【解决方案1】:

这里最简单的方法可能是遍历树创建一个单独的映射来通过 id 引用对象:

// set up the map
var idMap = {};

// recursive collection function
function collect(item) {
    idMap[item.id] = item;
    // recurse through the children, if any
    (item.children || []).map(collect);
}

// kick off
collect(source);

现在你有一个类似{ 1: <Object>, 2: <Object>, ...} 的地图,并且使用单独的函数添加或删除子节点非常简单,例如:

function updateChildren(id, children) {
    var o = idMap[id];
    o.children = children;
}

您可能还想在这里做其他事情,例如根据新的孩子(或移除孩子)更新id映射,合并新老孩子等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 2021-09-06
    • 2018-09-24
    • 2020-01-26
    • 2022-01-13
    相关资源
    最近更新 更多