根据数组的长度遍历JSON

时间:2017-07-11 17:22:45

标签: javascript jquery json for-loop

说我有一个json

jsonData = {
   "id":"dfd",
   "properties":{
      "Pri":"2",
      "Brief Description":"asdf",
      "Description":"",
      "tree":{
        "var": "2",
        "rav": "3"
      }
    }   
}

和一个清单

var variableArray = ['properties', 'tree', 'var'];

如果我想访问var的值并进行编辑。在保持jsonData的值时如何做到这一点?

我已经尝试了

for (var i = 0; i < variableArray.length; i++) {
  jsonData = jsonData[variableArray[i]];
}
jsonData = 'new value';

但我无法再访问整个jsonData。

有什么方法可以实现这个目标?

2 个答案:

答案 0 :(得分:2)

JavaScript没有对属性的引用,这实际上是您尝试在那里使用的内容。

相反,您可以为自己提供一个遍历对象并在其中检索或分配属性的方法。在ES5及更早版本中,这是一个快速而又肮脏的东西:

function accessPath(obj, path, value) {
    var o = obj;
    var i = 0;
    var last = path.length - 1;
    while (i < last) {
       o = o[path[i]];
       ++i;
    }
    if (arguments.length < 3) {
        // Getting
        return o[path[last]];
    } else {
        // Setting
        return o[path[last]] = value;
    }
}

实例:

&#13;
&#13;
function accessPath(obj, path, value) {
    var o = obj;
    var i = 0;
    var last = path.length - 1;
    while (i < last) {
       o = o[path[i]];
       ++i;
    }
    if (arguments.length < 3) {
        // Getting
        return o[path[last]];
    } else {
        // Setting
        return o[path[last]] = value;
    }
}

var data = {
   "id":"dfd",
   "properties":{
      "Pri":"2",
      "Brief Description":"asdf",
      "Description":"",
      "tree":{
        "var": "2",
        "rav": "3"
      }
    }   
}

var path = ['properties', 'tree', 'var'];

console.log("Existing: " + accessPath(data, path));
accessPath(data, path, "new value");
console.log("Updated: " + accessPath(data, path));
console.log("Confirm: " + data.properties.tree.var);
&#13;
&#13;
&#13;

在ES2015 +中看起来非常相似,除了你如何检查是否提供value

不漂亮,但效率很高。

实际上,如果我们返回一个带有getter和setter的对象,我们可以更进一步,这看起来有点像属性引用,即使它实际上并非如此:

function makeAccessor(obj, path) {
    var o = obj;
    var i = 0;
    var last = path.length - 1;
    var lastName = path[last];
    while (i < last) {
       o = o[path[i]];
       ++i;
    }
    return {
        get value() {
            return o[lastName];
        },
        set value(value) {
            o[lastName] = value;
        }
    };
}

然后,获取访问者:

var accessor = makeAccessor(data, path);

使用它:

console.log(accessor.value);
accessor.value = "new value";

&#13;
&#13;
function makeAccessor(obj, path) {
    var o = obj;
    var i = 0;
    var last = path.length - 1;
    var lastName = path[last];
    while (i < last) {
       o = o[path[i]];
       ++i;
    }
    return {
        get value() {
            return o[lastName];
        },
        set value(value) {
            o[lastName] = value;
        }
    };
}

var data = {
   "id":"dfd",
   "properties":{
      "Pri":"2",
      "Brief Description":"asdf",
      "Description":"",
      "tree":{
        "var": "2",
        "rav": "3"
      }
    }   
}

var path = ['properties', 'tree', 'var'];

var accessor = makeAccessor(data, path);

console.log("Existing: " + accessor.value);
accessor.value = "new value";
console.log("Updated: " + accessor.value);
console.log("Confirm: " + data.properties.tree.var);
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以编写符合您需要的小助手readwrite - 注意data不会因使用read而改变

&#13;
&#13;
const read = (o, [k,...ks]) =>
  o ? k === undefined ? o
                      : read (o[k], ks)
    : undefined
    
const write = (o, [k,...ks], v) =>
  o ? ks.length === 0 ? (o[k] = v, null)
                      : write (o[k], ks, v)
    : undefined
    
const data = {
  "id":"dfd",
  "properties":{
    "Pri":"2",
    "Brief Description":"asdf",
    "Description":"",
    "tree":{
      "var": "2",
      "rav": "3"
    }
  }   
}

// read
console.log (read (data, ['properties', 'tree', 'var']))
// => 2
console.log (read (data, ['foo', 'bar', 'barf']))
// => undefined (signals failure)

// write
console.log (write (data, ['properties', 'tree', 'var'], 'new value'))
// => null (signals success)
console.log (write (data, ['foo', 'bar', 'barf'], 'new value')) 
// => undefined (signals failure)

// read updated value
console.log (read (data, ['properties', 'tree', 'var'])) 
// => "new value"
&#13;
&#13;
&#13;

顺便说一下,要添加到其他人身上。注释,JavaScript对象符号是JSON所代表的。 Notation 部分使JSON与&#34; JSO&#34;不同。 (JavaScript对象)。更简单地说,JSON是JavaScript对象的字符串表示。如果它不是字符串,你就会知道它不是JSON。