9

我试图弄清楚是否可以使用字符串作为路径来更新 JavaScript 对象。

在下面的示例中,我试图弄清楚如何使用 store>book>0>price我的路径来更新第一本书的价格。

我知道我可以通过写作来访问它,data['store']['book'][0]['price']但我需要能够动态地做到这一点。我尝试了几件事,但没有运气。有任何想法吗?

这需要适用于任何深度,而不是固定深度


数据:

 var data = { 
      "store": {
        "book": [ 
          { "category": "reference",
            "author": "Nigel Rees",
            "title": "Sayings of the Century",
            "price": 8.95
          },
          { "category": "fiction",
            "author": "Evelyn Waugh",
            "title": "Sword of Honour",
            "price": 12.99
          }
        ],
        "bicycle": {
          "color": "red",
          "price": 19.95
        }
      }
    }
var path = "store>book>0>price"

功能:

function updateObject(object, path, data) {
    var pathArray = path.split(">");
    // Some code here
} 
updateObject(data, path, "10.00");

更新

正如 felix 指出的那样,答案可以在这里找到。 JavaScript 对象的动态深度设置

这是我的场景的一个工作示例 http://jsfiddle.net/blowsie/Sq8j3/9/

4

4 回答 4

19
function updateObject(object, newValue, path){

  var stack = path.split('>');

  while(stack.length>1){
    object = object[stack.shift()];
  }

  object[stack.shift()] = newValue;

}
于 2013-02-26T15:52:04.590 回答
3

您想要更新您的方法签名以接受:您正在修改的对象、路径字符串以及您分配给最终路径属性的值。

function updateObject(data, path, value) {
        var pathArray = path.split(">");
        var pointer = data; // points to the current nested object
        for (var i = 0, len = pathArray.length; i < len; i++) {
            var path = pathArray[i];
            if (pointer.hasOwnProperty(path)) {
                if (i === len - 1) { // terminating condition
                    pointer[path] = value;
                } else {
                    pointer = pointer[path];
                }
            } else {
                // throw error or terminate. The path is incorrect
            }
        }
    }

或者递归。或使用while 循环。但这是一般的想法。

小提琴:http: //jsfiddle.net/Sq8j3/8/

于 2013-02-26T15:35:30.613 回答
1

调用对象有点令人困惑,data但这data也是函数的参数。因此,我已将参数的名称更改为newVal以清除此潜在问题。

这循环遍历路径并不断重置一个名为的变量,该变量e通常从指向data对象开始,并在我们循环时变得更加具体。最后,您应该几乎可以引用确切的属性——我们使用路径的最后一部分来设置新值。

function updateObject(newVal, path) {
    var pathArray = path.split(">"),
        i = 0,
        p = pathArray.length - 1, // one short of the full path
        e = data; // "import" object for changing (i.e., create local ref to it)
    for (i; i < p; i += 1) { // loop through path
        if (e.hasOwnProperty(pathArray[i])) { // check property exists
            e = e[pathArray[i]]; // update e reference point
        }
    }
    e[pathArray[i]] = newVal; // change the property at the location specified by path to the new value
};

您可能需要添加一些内容来捕获错误。我已经在hasOwnProperty()电话中进行了检查,但您可能需要比这更详细的信息。

更新

之前在代码中犯了一个愚蠢的错误,但它现在应该可以工作了。正如这里所证明的那样。

于 2013-02-26T15:43:16.513 回答
0

重构使用字符串键访问嵌套的 JavaScript 对象

我明白了

var path = "store>book>0>price"
Object.byString = function(o, s) {
    var a = s.split('>');
    while (a.length) {
        var n = a.shift();
        if (n in o) {
            o = o[n];
        } else {
            return;
        }
    }
    return o;
}


function updateObject(data, path) {
  object2update= Object.byString(data, path);
} 
于 2013-02-26T15:31:21.137 回答