我已经使用 lodash 一段时间了,我真的很喜欢 _.set
和 _.get
方法。
我正在尝试解决一个问题,以获取其最终值为字符串的深层关键路径,但是当我太笨时。花了3个小时也没找到完美的解决方案:
const myObject = {
a: 'myObject.a',
b: {
ba: 'myObject.b.ba',
bb: ['myObject.b.bb[0]'],
},
c: [
{ ca: 'myObject.c[0].ca' },
],
};
所以我有 myObject
(这在现实生活中嵌套得更多),我想获取值的路径,但只是最后一个。
该方法类似于 getDeepPaths(myObject)
,在本例中将返回:['myObject.a', 'myObject.b.ba', 'myObject.b.bb [0]', 'myObject.c[0].ca']
以前有人解决过类似的问题吗?
最佳答案
递归其实并不难。以下是解决此问题的方法:
const myObject = {
a: 'myObject.a',
b: {
ba: 'myObject.b.ba',
bb: ['myObject.b.bb[0]'],
},
c: [
{ ca: 'myObject.c[0].ca' },
],
};
var stringLeaves = function(path, obj) {
if (typeof obj === 'string') {
return [path]
}
return Object.keys(obj)
.filter(k => obj.hasOwnProperty(k))
.map(k => stringLeaves(path + '.' + k, obj[k]))
.reduce((a,x) => a.concat(x), []); // this line flattens the array
};
console.log(stringLeaves('myObject', myObject));
这项工作是由 stringLeaves
函数完成的。在此函数中:
- 如果作为参数传入的
obj
是字符串,则仅返回当前路径。 - 否则我们假设该对象是一个数组或一个通用对象,在这种情况下我们会迭代它的属性:
- 对于每个属性,通过传入调整后的路径(当前路径 + 新属性名称)以及驻留在该特定键的对象/值,递归调用
stringLeaves
。
- 对于每个属性,通过传入调整后的路径(当前路径 + 新属性名称)以及驻留在该特定键的对象/值,递归调用
该函数的约定是返回所有可能匹配的数组。这就是原因:
- 对于标量字符串值,我返回一个数组(以保持一致)
- 我有
.reduce((a,x) => a.concat(x), []);
行:将数组数组转换为包含所有数组的数组原始数组中存在的值。
请注意,该函数无法推断出您的对象名为 myObject
,因此我将该名称作为初始路径传递。
关于javascript - 基于递归的深层 key 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49611224/