如何在JSON对象中获得特定级别的节点

How to get the nodes at a particular level in a JSON object?

本文关键字:节点 JSON 对象      更新时间:2023-09-26

我正试图弄清楚如何从顶层获得JSON对象中特定级别的所有值。我知道如何以以下方式遍历所有对象:

for (var key in dirTree) {
    if(dirTree.hasOwnProperty(key)) {
      var val = dirTree[key];
      console.log(JSON.stringify(val));
    }
  }

但是我要怎么做才能从顶部到达特定的级别呢?

是的,Icepickle是对的。递归是处理这个问题的最好方法。下面是一个解决方案:

var testObj = {
  "one": {
    "1": {"msg": "msg1"},
    "2": {"msg": "msg2"},
    "3": {"msg": "msg3"}
  },
  "two": {
    "1": {"msg": "msg4"},
    "2": {"msg": "msg5"},
    "3": {"msg": "msg6"}
  }
};
function follow(obj, n){
  if (n == 1) {
    return Object.keys(obj).map(function(k){
      return obj[k];
    });
  }
  else return Object.keys(obj).map(function(k){
    return follow(obj[k], n-1);
  });
}
console.log(follow(testObj, 2));

http://jsbin.com/boqekunaba/edit?js、控制台、输出

如前所述,这将返回示例JSON树的第二层。你可以把n换成3看看会发生什么。结果是数组,以保持简洁。这是使用map方法的结果,该方法是编写for循环的快捷方式。如果我们只是想要对象,我们需要稍微调整一下这段代码。

通过递归对象的属性可以做到这一点。在这种情况下,我的示例不是很有表现力,它不会告诉你它是否在路径中没有找到属性,它只会返回未知路径的undefined,但它会返回最后一个属性包含的任何内容(在我的示例中,它应该返回'text')

当然,如果字符串是静态的,这个示例没有任何意义,但如果它来自用户输入或来自您控制之外接收的值,您可以使用它,否则您当然可以简单地从jsonObject.complex.english.title;)

开始

'use strict;';
var jsonObject = {
  complex: {
    english: {
      title: 'text'
    }
  }
};
/*
 * @method getPath
 *
 * @param obj Object for which a path must be found
 * @param path String value indicating the path that will be traversed, joined with .
 *
 * @returns undefined or the object that was found at the specified path
 */
function getPath(obj, path) {
  var arrayPath, 
      propertyName,
      nextPath;
  console.log('getting path "' + path + '" for', obj);
  if (!obj) {
    // previous evaluation returned null, empty string, false, or undefined
    return;
  }
  if (!path) {
    // no path given, or path is empty string
    return obj;
  }
  arrayPath = path.split('.');
  propertyName = arrayPath[0];
  if (!propertyName) {
    // invalid path, return the current object
    return;
  }
  if (arrayPath.length === 1) {
    // no deeper searching required, return the value or undefined in case this object doesn't have the property
    return obj[propertyName];
  }
  // reassemble the left over string
  nextPath = arrayPath.slice(1, arrayPath.length).join('.');
  // search the next part of the path
  return getPath(obj[propertyName], nextPath);
}
function displayResults(inputSelector, outputSelector) {
  var inputEl = document.querySelectorAll(inputSelector)[0],
      outputEl = document.querySelectorAll(outputSelector)[0];
  
  if (inputEl && outputEl) {
    outputEl.innerHTML = JSON.stringify(getPath(jsonObject, inputEl.value));
  }
  // no submit ;)
  return false;
}
displayResults('#pathField', '#output');
<form onsubmit="return displayResults('#pathField', '#output');">
  <label for="pathField">Enter the path to find in the object</label>
  <input type="text" required pattern="['w.|'w]*" id="pathField">
  <button type="submit">Find and output path</button>
</form>
<div id="output"></div>