简体   繁体   English

Javascript通过数组路径更新嵌套对象中的值

[英]Javascript update values in nested object by array path

Given the nested object:给定嵌套对象:

{
    name: 'UK',
    toggled: false,
    active: false,
    children: [{
            name: 'Region 1',
            active: false,
            toggled: false,
            children: [{
                    name: 'Heathrow T1',
                    toggled: false,
                    active: false,
                    children: []
                },
                {
                    name: 'HTT',
                    toggled: false,
                    active: false,
                    children: []
                },
            ]
        },
        {
            name: 'Region 2',
            active: false,
            toggled: false,
            children: [{
                name: Gatwick North,
                active: false,
                toggled: false,
                children: []
            }]
        }
    ]
}

and the given path和给定的路径

['UK', 'Region 2', 'Gatwick North']

how can I manage to add active/toggled properties to true for the path in the nested object matching the above array.对于与上述数组匹配的嵌套对象中的路径,我如何设法将 active/toggled 属性添加为 true。

The output should be the following:输出应如下所示:

{
    name: 'UK',
    toggled: true,
    active: true,
    children: [{
            name: 'Region 1',
            active: false,
            toggled: false,
            children: [{
                    name: 'Heathrow T1',
                    toggled: false,
                    active: false,
                    children: []
                },
                {
                    name: 'HTT',
                    toggled: false,
                    active: false,
                    children: []
                },
            ]
        },
        {
            name: 'Region 2',
            active: true,
            toggled: true,
            children: [{
                name: 'Gatwick North',
                active: true,
                toggled: true,
                children: []
            }]
        }
    ]
}

I was trying to implement this with recursion with no success so far.到目前为止,我试图用递归来实现这一点,但没有成功。 I was searching through questions and none of them matched my current situation.我正在搜索问题,但没有一个与我目前的情况相符。

simple example of using recursion, explanations are in code as comments使用递归的简单例子,解释在代码中作为注释

 const obj = {name: 'UK',toggled: false,active: false,children: [{name: 'Region 1',active: false,toggled: false,children: [{name: 'Heathrow T1',toggled: false,active: false,children: []},{name: 'HTT',toggled: false,active: false,children: []},]},{name: 'Region 2',active: false,toggled: false,children: [{name: 'Gatwick North',active: false,toggled: false,children: []}]}]}; const checkAndChange = (obj) => { // function that will check if name exists in array and change toggle and active properties const arr = ['UK', 'Region 2', 'Gatwick North']; if (arr.includes(obj.name)) { obj.toggled = true; obj.active = true; } } const recursion = (obj) => { const o = obj; checkAndChange(o); // check if name exists in array and change toggle and active properties if (o.children.length > 0) { // check if has children o.children.forEach(v => { // if has children do the same recursion for every children recursion(v); }); } return o; // return final new object } console.log(recursion(obj));
 .as-console-wrapper { max-height: 100% !important; top: 0; }

Use recursive method to find the path and update the value.使用递归方法查找路径并更新值。

 var obj = [{name: 'UK',toggled: false,active: false,children: [{name: 'Region 1',active: false,toggled: false,children: [{name: 'Heathrow T1',toggled: false,active: false,children: []},{name: 'HTT',toggled: false,active: false,children: []},]},{name: 'Region 2',active: false,toggled: false,children: [{name: 'Gatwick North',active: false,toggled: false,children: []}]}]}]; function FilterArray(temp2,i){ temp2.filter(function(el){ if(el['name']==path[i]){ el['toggled']=true; el['active']=true; if(i!=path.length-1){ FilterArray(el['children'],++i); } } }); } console.log("Before"); console.log(obj); var path=['UK', 'Region 2', 'Gatwick North']; FilterArray(obj,0); console.log("After"); console.log(obj);

Based on this answer on a very similar question :基于这个答案在一个非常类似的问题

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

Use it like this:像这样使用它:

var obj = {
  foo: { bar: 'baz' }
};

alert(deep_value(obj, ['foo','bar'])); // alerts "baz"

Extra : the same function can also be used for arrays额外:同样的函数也可以用于数组

var arr = [
  ['item 0.0', 'item 0.1'],
  ['item 1.0', 'item 1.1'],
  ['item 2.0', 'item 2.1'],
]
console.log(deep_value(arr, [2,1])); // logs "item 2.1"

Codepen代码笔

This will work for nested arrays.这将适用于嵌套数组。

parameters:参数:
- array : array to update - array :要更新的数组
- path : what to update ( [0] - array[0], [2,1] - array[2][1], etc. ) - path :要更新的内容( [0] - array[0], [2,1] - array[2][1], etc.
- data : data to assign - data :要分配的数据

    function updateArray(array, path, data) {
        const index = path.shift();
        if (path.length) {
            if (!Array.isArray(array[index])) {
                array[index] = [];
            }
            updateArray(array[index], path, data);
        } else {
            array[index] = data;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM