Javascript 通过数组路径更新嵌套对象中的值
Javascript update values in nested object by array path
给定嵌套对象:
{
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: []
}]
}
]
}
和给定的路径
['UK', 'Region 2', 'Gatwick North']
如何为匹配上述数组的嵌套对象中的路径添加 active/toggled 属性为真。
输出应如下所示:
{
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: []
}]
}
]
}
我试图用递归来实现它,但到目前为止没有成功。我正在搜索问题,其中 none 个符合我目前的情况。
使用递归方法查找路径并更新值。
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);
使用递归的简单示例,解释在代码中作为注释
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; }
基于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;
};
这样使用:
var obj = {
foo: { bar: 'baz' }
};
alert(deep_value(obj, ['foo','bar'])); // alerts "baz"
Extra:同样的功能也可以用于数组
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"
这适用于嵌套数组。
参数:
- array
:要更新的数组
- path
:要更新的内容 ([0] - array[0], [2,1] - array[2][1], etc.
)
- 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;
}
}
给定嵌套对象:
{
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: []
}]
}
]
}
和给定的路径
['UK', 'Region 2', 'Gatwick North']
如何为匹配上述数组的嵌套对象中的路径添加 active/toggled 属性为真。
输出应如下所示:
{
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: []
}]
}
]
}
我试图用递归来实现它,但到目前为止没有成功。我正在搜索问题,其中 none 个符合我目前的情况。
使用递归方法查找路径并更新值。
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);
使用递归的简单示例,解释在代码中作为注释
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; }
基于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;
};
这样使用:
var obj = {
foo: { bar: 'baz' }
};
alert(deep_value(obj, ['foo','bar'])); // alerts "baz"
Extra:同样的功能也可以用于数组
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"
这适用于嵌套数组。
参数:
- array
:要更新的数组
- path
:要更新的内容 ([0] - array[0], [2,1] - array[2][1], etc.
)
- 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;
}
}