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

アップデート

フェリックスが指摘したように、答えはここにあります。 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 に答える