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

时间:2015-10-07 17:46:06

标签: javascript json

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

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

但是如何从顶部进入特定级别呢?

2 个答案:

答案 0 :(得分:0)

通过递归对象的属性,您可以执行此操作。在这种情况下,我的样本不是非常富有表现力,它不会告诉你它是否在你的路径中找不到属性,它只会返回未定义的未知路径,但它会返回最后一个属性包含的内容(在我的示例中,它应该返回'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>

答案 1 :(得分:0)

是的,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,console,output

如上所述,这将返回示例JSON树的第二级。您可以将n更改为3以查看会发生什么。结果是数组以保持这种简洁。这是使用map方法的结果,map方法是编写for循环的快捷方式。如果我们只是想要对象,我们就必须再调整一下这些代码。