我有一个对象,在各个深度都有重复的键名。我想编写一个函数(普通JS),该函数返回与给定名称匹配的所有键的路径数组。
例如:
const obj = {
stuff: {
A: 'text'
},
deeperStuff: {
nested: {
A: ['data']
}
}
};
const func = (object, key) => {
...
};
console.log(func(obj, 'A'));
// [['stuff', 'A'], ['deeperStuff', 'nested', 'A']]
很抱歉,如果这是一个重复的问题,但我找不到适合我需要的答案。
预先感谢
P
答案 0 :(得分:2)
这样的事情怎么样...拿住对象并遍历其键以寻找匹配项。如果找到一个,则添加到哈希(我更改了输出类型)。如果值是另一个对象,则使用该嵌套对象递归。
const myObj = {
stuff: {
A: 'text'
},
deeperStuff: {
nested: {
A: ['data']
}
}
};
function findKeys(obj, desiredKey, path = [], results = {}) {
const keys = Object.keys(obj)
keys.forEach(function(key) {
const currentPath = path.concat([key])
if (key === desiredKey) {
results[currentPath.join('/')] = obj[key]
}
if (typeof obj[key] === "object") {
findKeys(obj[key], desiredKey, currentPath, results)
}
})
return results
}
// same functionality with your desired return type
function findKeyArray(obj, desiredKey, path = [], results = []) {
const keys = Object.keys(obj)
keys.forEach(function(key) {
const currentPath = path.concat([key])
if (key === desiredKey) {
results.push(currentPath); // changed this line
}
if (typeof obj[key] === "object") {
findKeyArray(obj[key], desiredKey, currentPath, results); // and this line ;)
}
})
return results
}
console.log(findKeys(myObj, "A"))
console.log(findKeyArray(myObj, "A"))
输出
{
deeperStuff/nested/A: ["data"],
stuff/A: "text"
}
[["stuff", "A"], ["deeperStuff", "nested", "A"]]
答案 1 :(得分:1)
您可以使用迭代和递归方法,而无需存储结果的实际访问路径。
function getDeeperPath(object, key) {
return Object
.entries(object)
.reduce((r, [k, v]) => {
if (k === key) {
return r.concat(k);
}
if (v && typeof v === 'object') {
getDeeperPath(v, key).forEach(t => r.push([k, ...t]));
}
return r;
}, []);
}
const object = { stuff: { A: 'text' }, deeperStuff: { nested: { A: ['data'] } } };
console.log(getDeeperPath(object, 'A'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:0)
这是一个使用 object-scan 的解决方案。简洁并允许在搜索路径中使用复杂的模式,但您正在添加依赖项 - 因此这里需要权衡。
// const objectScan = require('object-scan');
const myObj = { stuff: { A: 'text' }, deeperStuff: { nested: { A: ['data'] } } };
console.log(objectScan(['**.A'])(myObj));
// => [ [ 'deeperStuff', 'nested', 'A' ], [ 'stuff', 'A' ] ]
console.log(objectScan(['**.stuff.A'])(myObj));
// => [ [ 'stuff', 'A' ] ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>
免责声明:我是object-scan
的作者