我使用Firebase
,他们update
功能可以让用户使用以下语法多位置更新:如何获取对象中嵌套属性的keypath?
newData['users/abc/age'] = 23
newData['users/xyz/hair'] = 'blue'
firebase.database().ref().update(newData)
我工作的一个实用功能,将扁平化深度嵌套的对象到像newData
的对象。这涉及递归迭代对象并在循环下降时跟踪键。
到目前为止,我有这样的(它只是添加路径层,以数组现在一旦算法中是正确的,我可以简单的将.join('/')
):
function getKeypaths(obj, paths = []) {
let keys = Object.keys(obj)
for (let i = 0; i < keys.length; i++) {
let propName = keys[i]
paths.push(propName)
if (typeof obj[propName] === "object" && typeof obj[propName] !== null) {
console.log("PUSHING PATH", propName, paths)
getKeypaths(obj[propName], paths)
} else {
console.log("val", obj[propName], paths)
}
}
}
let obj = {
a: {
b: {
c: {
d: 1
}
},
x: {
y: {
z: 2
}
}
}
}
getKeypaths(obj)
当我运行这一点,console.log
输出看起来是这样的:
PUSHING PATH a [ 'a' ]
PUSHING PATH b [ 'a', 'b' ]
PUSHING PATH c [ 'a', 'b', 'c' ]
val 1 [ 'a', 'b', 'c', 'd' ]
PUSHING PATH x [ 'a', 'b', 'c', 'd', 'x' ]
PUSHING PATH y [ 'a', 'b', 'c', 'd', 'x', 'y' ]
val 2 [ 'a', 'b', 'c', 'd', 'x', 'y', 'z' ]
正如你所看到的,循环保持前值的路径它开始挖下一个非对象的值时。输出的最后一行应改为:val 2 [ 'a', 'x', 'y', 'z' ]
我又试图清除path
阵列一旦循环恢复到以前的水平:
function getKeypaths(obj, paths = []) {
let keys = Object.keys(obj)
for (let i = 0; i < keys.length; i++) {
let propName = keys[i]
if (propName) paths.push(propName)
if (typeof obj[propName] === "object" && typeof obj[propName] !== null) {
console.log("PUSHING PATH", propName, paths)
getKeypaths(obj[propName], paths)
paths.length = 0
} else {
console.log("val", obj[propName], paths)
}
}
}
getKeypaths(obj)
但是,这不仅造成了环路忘记path
之前其目前的水平后第一个value
:
PUSHING PATH a [ 'a' ]
PUSHING PATH b [ 'a', 'b' ]
PUSHING PATH c [ 'a', 'b', 'c' ]
val 1 [ 'a', 'b', 'c', 'd' ]
PUSHING PATH x [ 'x' ]
PUSHING PATH y [ 'x', 'y' ]
val 2 [ 'x', 'y', 'z' ]
有什么建议吗?如果有更直接的方法可以打开助手库。
一个极好的解决方案,完美的作品。如果有人需要这个类似的目的,请注意:**(a)**数组扩展到'index'上键入的'objs',即'jsonPointer.dict(['a','b','c' ])== {1:'a',2:'b',3:'c'}'(Firebase会对它们进行处理),**(b)**将会添加'null' s和'未定义'的结果''对象' - 我只是添加了一个简单的循环来删除这些值之前推到firebase,[片段在这里](https://runkit.com/brandonmp/583c60989f00610014775b5f) – Brandon