如何从JSON获取嵌套的深属性值,其中key在变量中?

时间:2015-05-28 07:53:25

标签: json angularjs node.js

我想用我的密钥在变量中的JSON对象嵌套密钥绑定我的ng-model。

var data = {"course":{"sections":{"chapter_index":5}}};
var key = "course['sections']['chapter_index']"

这里我想从数据JSON对象中获取值5.

  

我找到了将“course.sections.chapter_index”转换为数组符号的解决方案,如课程['sections'] ['chapter_index']这个。但不知道如何从数据中提取价值

 <script type="text/javascript">
    var BRACKET_REGEXP =  /^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/;
    var APOS_REGEXP = /'/g;
    var DOT_REGEXP = /\./g;
    var FUNC_REGEXP = /(\([^)]*\))?$/; 
        var preEval = function (path) {
    var m = BRACKET_REGEXP.exec(path);
    if (m) {
      return (m[1] ? preEval(m[1]) : m[1]) + m[2] + (m[3] ? preEval(m[3]) : m[3]);
    } else {
      path = path.replace(APOS_REGEXP, '\\\'');
      var parts = path.split(DOT_REGEXP);
      var preparsed = [parts.shift()];    // first item must be var notation, thus skip
      angular.forEach(parts, function (part) {
        preparsed.push(part.replace(FUNC_REGEXP, '\']$1'));
      });
      return preparsed.join('[\'');
    }
  };
  var data = {"course":{"sections":{"chapter_index":5}}};
  var obj = preEval('course.sections.chapter_index');
  console.log(obj);

</script>

希望这也有助于他人。我即将关闭解决方案,但不知道如何从JSON获取嵌套值。

6 个答案:

答案 0 :(得分:1)

var jsonObject={"address": {line": {"line1": "","line2": ""}}}; 

var modelName="address.line.line1";

var result =getDescendantPropValue(jsonObject, modelName); function getDescendantPropValue(obj, modelName) {
        console.log("modelName " + modelName);
        var arr = modelName.split(".");
        var val = obj;
        for (var i = 0; i < arr.length; i++) {
            val = val[arr[i]];
        }
        console.log("Val values final  : " + JSON.stringify(val));
        return val;
        }

答案 1 :(得分:1)

这可能也是一个很好的解决方案

getDeepnestedValue(object: any, keys: string[]) {
    keys.forEach((key: string) => {
        object = object[key];
    });
    return object;
}

答案 2 :(得分:0)

您正在尝试将“点表示法”和“括号表示法”结合起来访问对象中的属性,这通常不是一个好主意。

来源:"The Secret Life of Objects"

这是另一种选择。

var stringInput = 'course.sections.chapter_index'  
var splitInput = stringInput.split(".")  
data[splitInput[1]]][splitInput[2]][splitInput[3]] //5  
//OR: Note that if you can construct the right string, you can also do this:  
eval("data[splitInput[1]]][splitInput[2]][splitInput[3]]")

基本上,如果在字符串上使用eval,它将评估一个语句。 现在你只需要创建正确的字符串!你可以使用上面的方法,或调整你当前的实现,只需去

eval("data.course.sections.chapter_index") //5

来源MDN Eval文档。

答案 3 :(得分:0)

var data = {
    "course": {
        "sections": {
            "chapter_index": 5
        }
    }
};
var key = "course['sections']['chapter_index']";

var keys = key.replace(/'|]/g, '').split('[');

for (var i = 0; i < keys.length; i++) {
    data = data[keys[i]];
}
console.log(data);

答案 4 :(得分:0)

最简单的解决方案,可以满足您的需求:

var data = {"course":{"sections":{"chapter_index":5}}};
var key = "course['sections']['chapter_index']";

with (data) {
  var value = eval(key);
}

console.log(value);
//=> 5

请注意,您应该确保key来自受信任的来源,因为它是eval d。

使用witheval被认为是危险的,并且有充分的理由,但这可能是其合法使用案例中的一小部分。

答案 5 :(得分:0)

如果您不想使用eval,则可以执行一次线性减少:

var data = {"course":{"sections":{"chapter_index":5}}};
var key = "course['sections']['chapter_index']"
key.split(/"|'|\]|\.|\[/).reduce((s,c)=>c===""?s:s&&s[c], data)