2017-11-25 78 views
1

我想創建一個函數,接受對象中的路徑並使該關鍵。例如,如果我想更新城市,這是一個公司的子對象,這是一個屬性的子對象,我可以這樣做: originalObj ['property'] [''公司] ['城市'] =測試如何使用字符串作爲關鍵更新對象

這裏是我到目前爲止的代碼:

function updateObj(path, value){ 
    let valuePath = path.split(',') 
    let key='' 
    for(let i=0; i<valuePath.length ; i++){ 
    key = key+`[valuePath[${i}]]` 
    } 
    //key = [valuePath[0]] [valuePath[1]] [valuePath[2]] 
    originalObj[key] = value 
    } 

setObj('property,company,city', test) 
+0

哦,有趣。這並不難,但它在JavaScript 101課程中提供了一個很好的家庭作業練習。 – melpomene

+0

你有什麼嘗試過......有什麼問題? – vol7ron

回答

1
function updateObj(obj, path, value){ 
path.split(",").slice(0,-1).reduce((obj, key) => obj[key] || (obj[key] = {}), obj)[path.split(",").pop()] = value; 
} 
+1

這是一個令人驚歎的單行程,不應該在任何人的代碼中使用。 –

+0

冗餘拆分 – Intervalia

+0

@intervalia仍然比聲明或IIFE更短以緩存它 –

2

你可以保存路徑的最後一個鍵並使用臨時對象爲獲得最終的用於分配值的對象。

function updateObj(path, value) { 
 
    var valuePath = path.split(','), 
 
     last = valuePath.pop(), 
 
     temp = object; 
 

 
    for (let i = 0; i < valuePath.length; i++) { 
 
     temp = temp[valuePath[i]]; 
 
    } 
 
    temp[last] = value; 
 
} 
 

 
var object = { property: { company: { city: 'London' } } }; 
 

 
updateObj('property,company,city', 'New York'); 
 

 
console.log(object);

隨着Array#reduce

function updateObj(path, value) { 
 
    var valuePath = path.split(','), 
 
     last = valuePath.pop(); 
 

 
    valuePath.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value; 
 
} 
 

 
var object = {}; 
 

 
updateObj('property,company,city', 'New York'); 
 

 
console.log(object);

0

試試這個:

function setObj(originalObj, path, value){ 
    var parts = path.split(','); 
    var lastKey = parts.pop(); 
    var obj = originalObj; 

    parts.forEach(
    function(key) { 
     key = key.trim(); 
     obj[key] = obj[key] || {}; 
     obj = obj[key]; 
    } 
); 

    obj[lastKey] = value; 
} 

    var originalObj = {}; 
    var test = "This is a test"; 
    setObj(originalObj, 'property,company,city', test) 

    console.log(JSON.stringify(originalObj,0,2)); 

它遍歷列表併爲除最後一個以外的所有列創建子對象。然後它使用最後的密鑰來存儲value

此代碼的優點是您不會假定原始對象變量名稱。而且,如果你想要它是純粹的,而不是影響原始的對象結構,那麼你可以做出這些小的改變:

function setObj(originalObj, path, value){ 
    var parts = path.split(','); 
    var lastKey = parts.pop(); 
    var newObj = Object.assign({}, originalObj); 
    var obj = newObj; 

    parts.forEach(
    function(key) { 
     obj[key] = Object.assign({}, obj[key] || {}); 
     obj = obj[key]; 
    } 
); 

    obj[lastKey] = value; 
    return newObj; 
} 

    var originalObj = {animals: {dog:"bark",cat:"meow"},property:{company:{name:"Fred's Things"}}}; 
    var test = "This is a test"; 
    var result = setObj(originalObj, 'property,company,city', test) 


    console.log(JSON.stringify(originalObj,0,2)); 
    console.log(JSON.stringify(result,0,2)); 
相關問題