【问题标题】:Modifying value in multidimensional array by path in array (or any) format通过数组(或任何)格式的路径修改多维数组中的值
【发布时间】:2015-06-24 12:50:59
【问题描述】:

我有一个多维数组,代表一个可能无限的深层类别树菜单,如下所示

this.tree = [{
    "title": "1. dragon-breath",
    "items": []
}, {
    "title": "2. moiré-vision",
    "items": [{
        "title": "2.1. tofu-animation",
        "items": [{
            "title": "2.1.1. spooky-giraffe",
            "items": []
            }, {
                "title": "2.1.2. bubble-burst",
                "items": []
            }],
    }, {
        "title": "2.2. barehand-atomsplitting",
        "items": []
    }],
}, {
    "title": "3. unicorn-zapper",
    "items": []
}, {
    "title": "4. romantic-transclusion",
    "items": []
}];

然后我有一个指向树叶的数组路径,它会随时间动态变化,看起来像这样

var path = [0]

下次可以这样

var path = [1][1]

或者这个

var path = [1][0][1]

现在我需要改变这条路径所代表的leave的title属性。我找不到任何体面的方法来做到这一点。唯一让我想到的是 eval 函数,

eval('tree'+getStringPathByArrayPath([1,0,1])+'.name = "'+updatedName+'"')

我觉得有点邪恶,而且我使用这个函数作为 angular ng-model (getter/setter),所以我不希望浏览器一遍又一遍地评估这个。

有什么不错的方法可以解决这个问题,还是我对这个问题有不好的方法?

PS:我不能只递归地遍历路径数组并逐个节点地到达正确的树,因为没有通过引用传递,每次我将一个子节点分配给变量时,我都会得到一份副本(但我需要改变原来的)。

感谢您的宝贵时间。

【问题讨论】:

  • 不,路径不能这样。
  • 查看一些在 jsfiddle 中运行的代码会有所帮助。
  • @theonlygusti 你能解释一下原因吗?
  • 对不起,我的错 - 路径实际上看起来像 [0] 或 [1,1] 或 [1,0,1]

标签: javascript angularjs multidimensional-array


【解决方案1】:

虽然 Javascript 是按值传递的,但任何持有对象的变量的值都是对该对象的引用。传递这样的变量将传递引用,而不是对象的副本。所以这会改变你的树:

var node = this.tree[path[0]];
for (var i = 1 ; i < path.length ; i++) {
  node = node.items[path[i]];
}
node.title = updatedName;

【讨论】:

  • 谢谢,这是一个深思熟虑的回应,它帮助我解决了我的难题。我仍然不知道如何在没有 jsons(只是一个多维数组)的情况下解决类似的问题,但我现在不需要它。所以非常感谢:)
【解决方案2】:

假设您有一个 Array 定义要访问的属性以获得所需的值;

var path = [1, 0, 1];
//          x  y  z

你也有一些对应的对象

var obj = [
// y     0           1        // x
// z   0    1      0    1     //
    [['a', 'b'], ['c', 'd']], // 0
    [['e', 'f'], ['g', 'h']]  // 1
];

你可以写一个函数来获取这个值

function followPath(root, path) {
    var i;
    for (i = 0; i < path.length; ++i)
        root = root[path[i]];
    return root;
}

在这个例子中你会得到

followPath(obj, path); // "f"

【讨论】:

  • 感谢回复,但正如我在 PS 中所说,我需要修改数组中的那些值(具有角度 getter/setter)并且因为 JS 没有通过引用传递,所以修改这个返回的节点你的函数不会修改原来的......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-24
  • 2016-07-29
  • 2023-03-29
相关资源
最近更新 更多