我一直坚持认为JS中的一个简单问题。我想要做的是我有一个未知的深度JSON,如此:
"A": {
"B": {
"e": "",
"f": {
"g": "",
"h": ""
},
"C": {
"i": "",
"j": "",
"k": "",
"l": ""
},
"D": {
"m": "",
"n": "",
"o": "",
"p": ""
}...
json可以是任何级别的深度。我想要实现的是为每个元素创建一个祖先数组+本身,所以对于“p”,它将是["A", "B", "D", "p"]
我试过像这样使用递归:
build(json, '', []);
function build(json, path, assets){
for (var elem in json) {
if(json.hasOwnProperty(elem)){
if(json[elem] == 0){
assets.push(elem);
//do stuff with the array
assets.pop();
} else {
var parent = path + '/' + elem;
assets.push(parent);
build(json[elem], parent, assets);
return;
}
}
}
}
这是该函数的简化版本,该部分无法正常工作。我背后的想法是遍历每个元素,如果它没有子元素,我追加当前元素并使用它(我不需要保留数组,仅用于该用途)如果它有子元素,我追加当前元素元素并以递归方式为当前元素调用该方法。
解决方案一直有效,直到达到第二级,因此对于“e”,“f”,“C”,“D”它会正确生成,但在去孩子之前会停止。
我错过了什么?
答案 0 :(得分:0)
我无法完全遵循您的代码,所以我只是从头开始编写解决方案。
值得注意的是,我不确定== 0
检查在您的代码中做了什么(可能与我的typeof(...) !== 'object'
相同?),我不明白assets
和path
是有意义的。
var obj = {
"A": {
"B": {
"e": "",
"f": {
"g": "",
"h": ""
},
"C": {
"i": "",
"j": "",
"k": "",
"l": ""
},
"D": {
"m": "",
"n": "",
"o": "",
"p": ""
},
}
}
};
function getPaths(obj, sofar) {
if (sofar === undefined) {
sofar = [];
}
// Leaf node, just return the path
if (typeof(obj) !== 'object') {
return [sofar];
}
// Interior node
var paths = [];
Object.keys(obj).forEach(function (k) {
// For each child, recurse and concat
paths = paths.concat(getPaths(obj[k], sofar.concat([k])));
});
return paths;
}
console.log(getPaths(obj));
// Output:
// [ [ 'A', 'B', 'e' ],
// [ 'A', 'B', 'f', 'g' ],
// [ 'A', 'B', 'f', 'h' ],
// [ 'A', 'B', 'C', 'i' ],
// [ 'A', 'B', 'C', 'j' ],
// [ 'A', 'B', 'C', 'k' ],
// [ 'A', 'B', 'C', 'l' ],
// [ 'A', 'B', 'D', 'm' ],
// [ 'A', 'B', 'D', 'n' ],
// [ 'A', 'B', 'D', 'o' ],
// [ 'A', 'B', 'D', 'p' ] ]
答案 1 :(得分:0)
您可以为受访节点使用数组,并将其用作结果的一部分。
function getPath(object, path) {
path = path || [];
Object.keys(object).forEach(function (key) {
if (object[key] && typeof object[key] === 'object') {
return getPath(object[key], path.concat(key));
}
console.log(path.concat([key,object[key]]).join('/'));
});
}
var data = { A: { B: { e: "1", f: { g: "2", h: "3" }, C: { i: "4", j: "5", k: "6", l: "7" }, D: { m: "8", n: "9", o: "10", p: "11" } } } };
getPath(data);

.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)
从代码中删除return语句使它对我有用。
https://jsbin.com/deqelaj/edit?html,js,console
var assets = [];
function build(json, path, assets){
for (var elem in json) {
if(json.hasOwnProperty(elem)){
if(json[elem] == 0){
assets.push(elem);
//do stuff with the array
assets.pop();
} else {
var parent = path + '/' + elem;
assets.push(parent);
console.log(assets)
build(json[elem], parent, assets);
}
}
}
}
var json = {
"A": {
"B": {
"e": "",
"f": {
"g": "",
"h": ""
},
"C": {
"i": "",
"j": "",
"k": "",
"l": ""
},
"D": {
"m": "",
"n": "",
"o": "",
"p": ""
}
}
}
}
build(json, '', assets);
console.log(assets)
答案 3 :(得分:0)
使用reduce
和concat
const build = (data, path = []) =>
data == null
? []
: Object (data) === data
? Object.entries (data) .reduce ((acc, [ k, v ]) =>
acc.concat (build (v, [ ...path, k ])), [])
: [ [ ...path, data ] ]
const mydata =
{ A: { B: { e: '1'
, f: { g: '2'
, h: '3'
}
, C: { i: '4'
, j: '5'
, k: '6'
, l: '7'
}
, D: { m: '8'
, n: '9'
, o: '10'
, p: '11'
}
}
}
}
console.log (build (mydata))
// [ ['A','B','e','1'],
// ['A','B','f','g','2'],
// ['A','B','f','h','3'],
// ['A','B','C','i','4'],
// ['A','B','C','j','5'],
// ['A','B','C','k','6'],
// ['A','B','C','l','7'],
// ['A','B','D','m','8'],
// ['A','B','D','n','9'],
// ['A','B','D','o','10'],
// ['A','B','D','p','11'] ]