我有一个像这样的数组跟踪父对象的类似:
var object = {
'Shirt': {
'Color':'Blue',
'Size':'Large'
},
'Pants': {
'Color':'White',
'Size':'Medium',
}
}
我正在编写一个实时对象操作类型的东西,并且正在跟踪它们所在的对象。该数组如下所示:
var objectPath = ['Shirt', 'Color'];
现在我需要使用该数组来创建一个选择器,它允许我操纵对象路径中的数据,最终得到类似的东西。
selector = object['Shirt']['Color'];
我可以这样做:selector = 'Yellow'
它会改变对象中的相应选择。
我尝试了这个,但我无法将数组转换为选择器:
objectPath.forEach(function(path, i) {
selector += '[path]';
});
我知道我正在创建一个新的字符串,我无法弄清楚如何使用eval或类似的东西来做这件事。
答案 0 :(得分:3)
let obj = {
'shirt': {
'color': 'blue'
}
},
ref = obj,
selectors = ['shirt', 'color']
newValue = 'yellow';
selectors.forEach( (selector, index) => {
if(index === selectors.length - 1) ref[selector] = newValue
else ref = ref[selector];
})
console.log(obj.shirt.color)
如果你想操纵原始对象,你需要在最终属性之前建立路径,然后将该属性设置为新值。
答案 1 :(得分:2)
你可以Array.prototype.reduce在每个'路径'迭代上获得下一个嵌套级别:
const data = {
one: {
two: {
three: {
four: 'five'
}
}
}
}
const path = ['one', 'two', 'three', 'four']
const value = path.reduce((a, v) => a[v], data);
console.log(value)
你甚至可以创建一个接受'path'数组和对象的函数,如果路径错误则返回一个值或'null':
// function
const objSelector = o => pathArr => (Array.isArray(pathArr))
? pathArr.reduce((a, c) => (a[c] != null) ? a[c] : null, o)
: null;
const data = {
one: {
two: {
three: {
four: 'five'
}
}
}
}
const path = ['one', 'two', 'three', 'four']
// use function
const value = objSelector(data)(path)
console.log(value)