【问题标题】:Iterate through a JSON Tree to retrieve Parent and Child Recursively遍历 JSON 树以递归方式检索父项和子项
【发布时间】:2019-04-28 21:16:40
【问题描述】:

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

父母
---- 孩子1
---- 孩子2
---- 儿童3
-------- Child31
-------- Child32
---- Child4

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

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

有没有办法获得特定格式的结果:

NoParent - 父母
父母 - 孩子1
父母 - Child2
父母 - Child3
Child3 - Child31
Child3 - Child32
父母 - Child4

【问题讨论】:

  • 请补充:数据、变量、试运行、结果、错误。
  • 当我运行代码时,我能够捕获密钥但无法识别其父节点。
  • 请补充缺失的部分。
  • 这是我正在使用的代码。
  • 哦,对不起。删除了 inneKey5。代码遍历示例 JSON 文件并检索所有键。但我想要的是保存父值并将其与子键一起显示。

标签: javascript node.js recursion iteration


【解决方案1】:

假设您的数据具有以下形式:

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);

【讨论】:

    【解决方案2】:

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

    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; }

    【讨论】:

    • 有没有办法只获取直接父级而不是整个树?
    • 它是,如果我知道你想要什么(如果没有想要的数据,这总是一个问题)。请添加结果。
    • 对我的问题进行了更改:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 2014-03-11
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多