簡體   English   中英

JavaScript在不知道級別的情況下將值分配給嵌套對象中的元素

[英]JavaScript assign value to element in nested object without knowing level

說我有一個這樣的對象:

a : {
  a1 : {
    a2: true
  } 
}

我將所有路徑保存在數組中:

[a1, a2]

如果我想為a [“ a1”] [“ a2”]賦值,這很簡單:

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

但是,當我有這樣的3級路徑時:

[a1, a2, a3]

我必須手動編寫如下代碼:

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

有沒有一種方法可以自動處理任何級別的路徑,這樣我就不必在每種情況下都將其明確化?

請注意,“ a”可能會非常復雜,因此我只想為該特定元素分配值,而不涉及其余部分。

您可以使用以下路徑迭代遍歷對象:

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

請注意,路徑中的節點是字符串。

您可以通過幾種方式訪問​​屬性:

使用循環:

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

都是優雅的解決方案,我遞歸的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);

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

當然,這是一個簡單的循環:

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM