2017-11-25 47 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)); 
相关问题