从字符串路径动态更新 JavaScript 对象 [重复]

Posted

技术标签:

【中文标题】从字符串路径动态更新 JavaScript 对象 [重复]【英文标题】:Dynamically updating a JavaScript object from a string path [duplicate] 【发布时间】:2013-02-12 03:04:19 【问题描述】:

我正在尝试确定是否可以使用字符串作为路径来更新 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 指出的,答案可以在这里找到。 Dynamic deep setting for a JavaScript object

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

【问题讨论】:

@mplungjan:不一定。它也适用于for 循环。查看链接的问题。 虽然相关问题非常相似,但并没有解决更新对象的问题 @Blowsie:你的意思是像给属性赋值的问题?如果不是,你是什么意思? 你是对的。这两个可以:***.com/q/13719593/218196、***.com/q/6842795/218196。 为什么投反对票?我认为这是一个很好的问题。我赞成它,但它只会把它带回 0... 【参考方案1】:
function updateObject(object, newValue, path)

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

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

  object[stack.shift()] = newValue;


【讨论】:

很有魅力,谢谢jsfiddle.net/blowsie/Sq8j3/11 整洁 就像复制品(以及我对它的重写),但没有测试对象是否存在。尽管如此,如果已知数据可以工作,一个非常紧凑的版本 很好,很好的解决方案。 很棒的解决方案。我一直想知道如何做到这一点。 这是我见过的最好的。我也为 get、set 和 add 做了扩展:embed.plnkr.co/kwF83lMQtKb6Vb8aP8jt【参考方案2】:

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

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 loop。但这是大意。

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

【讨论】:

感谢您的努力,对我来说不太适用.. jsfiddle.net/blowsie/Sq8j3 已修复:jsfiddle.net/Sq8j3/8 这对我来说效果很好!!专门用于更新对象中的多个路径!谢谢!【参考方案3】:

您将对象称为datadata 也是您的函数的参数,这有点令人困惑。因此,我已将参数名称更改为 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() 呼叫进行了检查,但您可能需要比这更详细的信息。

更新

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

【讨论】:

感谢您的努力,对我来说不太好jsfiddle.net/blowsie/Sq8j3/2 感谢您对所做努力的认可 :-) 我在代码中犯了几个错误,现在已更正。不幸的是,这仍然不太正确,但你可以看到一些事情正在开始发生......jsfiddle.net/Sq8j3/10 @Blowsie 现已修复。无论如何,我看到你现在有一个正确(更简洁)的答案,但我不喜欢留下错误代码的想法! :-)【参考方案4】:

重构Accessing nested JavaScript objects with string key

我明白了

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);
 

【讨论】:

这只适用于固定深度... 我知道我可以这样做,但这根本不够动态,如果我的数据有 100 层深度怎么办? 啊,你没有指定级别

以上是关于从字符串路径动态更新 JavaScript 对象 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Javascript从字符串动态调用对象方法

Javascript:通过将路径作为字符串传递给对象来从对象中获取深层价值[重复]

Javascript:通过将路径作为字符串传递给对象来从对象中获取深层价值[重复]

Javascript通过引用传递对象然后更新

JavaScript把项目本地的图片或者图片的绝对路径转为base64字符串blob对象在上传

从Javascript动态构建JSON对象列表[重复]