遍历JSON树以递归方式检索Parent和Child



我有一个JSON文件,从中检索所有密钥。我需要以父子关系的方式检索密钥。例如:

父级
----子级1
-----子级2
------子级3
--------子级31
----------子级32
-----子级4

这可以通过递归实现吗?为了遍历文件,我使用以下代码:

function runRecurse(objLevel) {
for (var innerKey in objLevel) {
if (objLevel[innerKey] !== null){
console.log(innerKey);
runRecurse(objLevel[innerKey]);    
}
}                     
}

有没有一种方法可以获得类似于特定格式的结果:

无父级-父级
父级-子级1
母级-子代2
子级3
子女3
子女32
父级-子女4

为了将所有键作为单个路径,您可以获取对象的条目,并通过检查值是否也是对象进行迭代,然后获取子键或仅获取结果的实际键。

function getKeys(object) {
return Object
.entries(object)
.reduce((r, [k, v]) =>
r.concat(v && typeof v === 'object'
? getKeys(v).map(sub => [k].concat(sub))
: k
),
[]
);
}
var data = { v1: { Cr: { getrt: { input: { R: { Cd: "nt", Ud: "ing", Pd: "g", Mr: "ng", Se: "ng", Pe: "ing", Psion: "g", Rt: "L", Cd2: "xsring", Cag: "xsngth", NnfigID: "xsng", CryFlag1: "xength", C2: "xength", Custo3: "xength", Cus4: "xngth", tars: "ns", taace: "h.0" }, Reqails: { Amber: "xsd:string", B: "x", KenMI: "xg", targas: "ns", targace: "h" }, Inqutails: { "Inqnt[]": { Ar: "x", B: "x", KI: "x", ts: "ns", tce: "h0" }, tas: "ns", tace: "h" }, Reqdy: { Ise: "Inq", Tnt: "x", Ald: "x", Fme: "x", Fmjke: "xtern", Mme: "xttern", Lame: "xs", Fals: { "Ado[]": { Addme: "x", Adde: "AdnalNam", taas: "", taace: "ht" }, Noents: "x", talias: "n", tapace: "h" }, Ad1: "xh", A2: "x", Ae1: "xs", St: "x", L1: "xs", L2: "xs", Cy: "x", Ste: "S", Pal: "x", Is: { "I[]": { Aine: "x", Set: "xth", L1: "x", L2: "x", C: "x", Se: "St", Pal: "n", Ape: "", tas: "ns", tpace: "" } } } } } } } },
result = getKeys(data);
console.log(result.map(a => a.join(' ')));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

最后一个父节点和最后一个节点:

function getKeys(object, parent = 'noParent') {
return object && typeof object === 'object'
? Object
.entries(object)
.reduce((r, [k, v]) => [...r, [parent, k], ...getKeys(v, k)], [])
: [];
}
var data = { v1: { Cr: { getrt: { input: { R: { Cd: "nt", Ud: "ing", Pd: "g", Mr: "ng", Se: "ng", Pe: "ing", Psion: "g", Rt: "L", Cd2: "xsring", Cag: "xsngth", NnfigID: "xsng", CryFlag1: "xength", C2: "xength", Custo3: "xength", Cus4: "xngth", tars: "ns", taace: "h.0" }, Reqails: { Amber: "xsd:string", B: "x", KenMI: "xg", targas: "ns", targace: "h" }, Inqutails: { "Inqnt[]": { Ar: "x", B: "x", KI: "x", ts: "ns", tce: "h0" }, tas: "ns", tace: "h" }, Reqdy: { Ise: "Inq", Tnt: "x", Ald: "x", Fme: "x", Fmjke: "xtern", Mme: "xttern", Lame: "xs", Fals: { "Ado[]": { Addme: "x", Adde: "AdnalNam", taas: "", taace: "ht" }, Noents: "x", talias: "n", tapace: "h" }, Ad1: "xh", A2: "x", Ae1: "xs", St: "x", L1: "xs", L2: "xs", Cy: "x", Ste: "S", Pal: "x", Is: { "I[]": { Aine: "x", Set: "xth", L1: "x", L2: "x", C: "x", Se: "St", Pal: "n", Ape: "", tas: "ns", tpace: "" } } } } } } } },
result = getKeys(data);
console.log(result.map(a => a.join(' ')));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

假设您的数据为以下形式:

const data = {
'parent': {
'child1': 1,
'child2': 2,
'child3': {
'child31': 31,
'child32': 32
},
'child4': 4
}
}

您对递归有正确的想法,但递归中需要的两个元素是:

  1. 有一个要终止的基本情况
  2. 重复使用(希望减少(值

在这种情况下,基本情况(1.(没有子级,所以我们编写这个函数,如果元素没有子级的话,它将返回true。您可能需要为数组更改它。

function isEmpty(obj) {
let numProperties = 0;
for (let property in obj) {
if (obj.hasOwnProperty(property)) {
++numProperties;
}
}
return numProperties === 0;
}

有了一个基本情况和一些数据,让我们递归它。你想把一个函数应用到每个父(键(和它的子(元素(,然后在每个子(2.(上调用它,所以我们为无序树写一个映射函数:

function mapParentChildPairs(f, obj) {
// If this element has no children, we have reached the end, so stop
if (isEmpty(obj)) {
return;
} else {
// Otherwise, get each key in the object
for (let item in obj) {
if (obj.hasOwnProperty(item)) {
// Apply the function to the key and its value
f(item, obj[item]);
// And recurse over the item at that key, which may be more objects
// or simply an atomic value that will end the recursion.
mapParentChildPairs(f, obj[item]);
}
}
}
}

您的示例使用了console.log,所以让我们将其作为函数传入:

mapParentChildPairs(console.log, data);

最新更新