1

次のようなオブジェクトがあるとします。

a : {
  a1 : {
    a2: true
  } 
}

そして、すべてのパスを配列に保存しました:

[a1, a2]

a["a1"]["a2"] に値を割り当てたい場合は、簡単です。

a["a1"]["a2"] = true;

ただし、次のような 3 レベルのパスがある場合:

[a1, a2, a3]

次のようなコードを手動で記述する必要があります。

a["a1"]["a2"]["a3"] = true;

すべてのケースで明示的にする必要がないように、任意のレベルのパスを自動的に処理する方法はありますか?

「a」は非常に複雑になる可能性があるため、この特定の要素にのみ値を割り当て、残りには触れないことに注意してください。

4

5 に答える 5

5

次のように、パスを使用してオブジェクトを繰り返しトラバースできます。

function setDeepProperty(obj, path, value)
{
    var curr = obj;

    for (var depth = 0; depth < path.length - 1; depth++)
    {
        curr = curr[path[depth]];
    }

    curr[path[path.length - 1]] = value;
}

これは、パスが有効であることを前提としています。path[depth] in curr必要に応じて確認してください。トラバーサルの最後のステップはループの外側で行われます。これはcurr、(必要に応じて) 配列を参照するのではなく、プリミティブ型に設定されるためです。つまり、元の型は変更されません。次に、あなたの例に従って:

var arr = {a1: {a2: { a3: false }}};
setDeepProperty(arr, ["a1", "a2", "a3"], true);

ここで、パス内のノードは文字列であることに注意してください。

于 2013-05-14T00:56:48.793 に答える
3

プロパティにアクセスするには、いくつかの方法があります。

ループを使用します。

var obj = {
        a1 : {
            a2: { a3: 'test' }
        } 
    },
    i = 0,
    keyPath = ['a1', 'a2', 'a3'],
    len = keyPath.length;

    for (; i < len; i++) {
        obj = obj[keyPath[i]];
    }

    console.log(obj);

あり(ただし、これevalはお勧めしません):

var obj = {
            a1 : {
                a2: { a3: 'test' }
            } 
        };

var value = eval('obj.' + keyPath.join('.'));

console.log(value);

同じ方法を使用して、特定のキー パスにプロパティを設定できます。

function setProperty(obj, keyPath, value) {
    var i = 0,
        len = keyPath.length - 1;

    for (; i < len; i++) {
        obj = obj[keyPath[i]];
    }

    obj[keyPath[i]] = value;
}
于 2013-05-14T00:54:49.763 に答える
1

すべてがエレガントなソリューションであり、再帰を伴う私の2セント:-

ここでテスト

var a = {
    a1: {
        a2: {
            a3: false
        }
    }
};

var path = ['a1', 'a2', 'a3'];

var valueToSet = true;
setValue(0, a);


function setValue(level, ob) {
  var prop = path[level];

  if (!ob.hasOwnProperty(prop)) {
    return;
  }
   if (level == (path.length - 1)) {
    ob[prop] = valueToSet;
    return;
   }

   return setValue(level + 1, ob[prop]);

}
console.log(a);
于 2013-05-14T01:03:35.253 に答える
0

確かに、それは単純なループです:

var a = {a1:{a2:{}}};

var path = ["a1", "a2", "a3"];
for (var o=a, i=0; i<path.length-1; i++)
    o = o[path[i]]; // notice that this will throw exception
                    // when the objects do not exist already
o[path[i]] = true;
于 2013-05-14T00:55:34.000 に答える
0

2 つの可能性があります。

  • 恐ろしい eval()。そのためのコードを提供することを拒否します
  • インアウト ループ:

コード:

var a={
  a1 : {
    a2 : {
      a3: false
    } 
  } 
};
var idx=["a1", "a2", "a3"];

function recReplace(o, i, v) {
  var ii=i.shift();
  if (i.length==0)
    o[ii]=v;
  else
   o[ii]=recReplace(o[ii],i,v);
  return o;
}

b=recReplace(a,idx,true); //or: a=recReplace(a,idx,true);
于 2013-05-14T00:54:03.033 に答える