2016-07-14 72 views
2

如果我有一个数组数组,每个数组都包含对象属性名称(字符串),如何递归地修改对象以检查属性是否存在并相应地添加它。数组中的最后一个值将作为给定属性的字符串值应用。递归添加对象属性

const propsToAdd = [ 
    ['propA', 'value'], 
    ['propB', 'propC', 'propD', 'value'], 
    ['propB', 'propF', 'value'] 
]; 

生成的对象将包含相关属性(相应嵌套),最终属性的值将等于数组中的最后一项。

const resultingObj = { 
    propA: 'value', 
    propB: { 
     propC: { 
      propD: 'value' 
     } 
     propF: 'value' 
    } 
}; 

我想递归创建这样一个对象,作为该阵列将是未知的长度,如将子阵列。

重要的是要注意,以下将不会发生并且不需要适应。

const propsToAdd = [ 
    ['propA', 'value'], 
    ['propA', 'value', 'value1'] 
]; 

把否则,value(为propA孩子)不能同时为一个属性值名称。

我该如何编写一个递归函数,将键/值对添加(并嵌套)到对象?

+0

是有限制亲的名单的深度perties? – abigwonderful

+0

不,没有。 – Himmel

+0

数值是否在这里?或字符串“值”@Himmel – Ayan

回答

3

createRec以嵌套形式递归创建对象。

function processInput(propsToAdd) { 
 
    var resultingObj = {}, 
 
    propArr; 
 

 
    for (var i = 0, len = propsToAdd.length; i < len; i += 1) { 
 
    propArr = propsToAdd[i]; 
 
    createRec(propArr, resultingObj); 
 
    } 
 

 
    return resultingObj; 
 
} 
 

 
function createRec(propArr, resultingObj, index) { 
 
    var prop, 
 
    value_Str = 'value'; 
 
    for (var j = index || 0, len1 = propArr.length; j < len1; j += 1) { 
 
    prop = propArr[j]; 
 
    if (!resultingObj[prop]) { 
 
     resultingObj[prop] = {}; 
 
    } 
 
    if (propArr[j + 1] === value_Str) { 
 
     resultingObj[prop] = propArr[j + 1]; 
 
     j += 1; 
 
    } else { 
 
     createRec(propArr, resultingObj[prop], j + 1); 
 
     j = len1; 
 
    } 
 
    } 
 
} 
 

 
console.log(processInput([ 
 
    ['propA', 'value'], 
 
    ['propB', 'propC', 'propD', 'value'], 
 
    ['propB', 'propF', 'value'] 
 
]));

+0

@Himmel请验证并让我知道你是否有顾虑。 – Ayan

+0

这很好,谢谢! – Himmel

0

这不是递归版本,但为什么不呢?

function createObj(propsToAdd){ 
    obj = {} 
    for(var i = 0; i < propsToAdd.length; i++){ 
     var tmp = obj; 
     var props = propsToAdd[i]; 
     for(var j = 0; j < props.length-2; j++){ 
      var prop_name = props[ j ]; 
      if(!(prop_name in tmp)) 
       tmp[ prop_name ] = {} 
      tmp = tmp[ prop_name ]; 
     } 
     if(props.length > 1) 
      tmp[ props[ j ] ] = props[ j + 1 ] 
     else 
      obj = props[0]; 
    } 
    return obj; 
} 
1

闭包在这里迭代要添加到对象的所有属性列表。

每当找到新属性时,都会创建一个新对象。 该新对象被发送进一步扩展。

每当我们到达属性列表的最后一个值时,它就会被分配给当前属性。

var addProperties = (function() { 
 

 
    var addProperties = function(object, properties) { 
 
    var currentProperty = properties.shift(); 
 
    if (properties.length === 1) { 
 
     object[currentProperty] = properties[0]; 
 
    } 
 
    else{ 
 
     if (!object.hasOwnProperty(currentProperty)) 
 
     object[currentProperty] = {}; 
 
     addProperties(object[currentProperty], properties); 
 
    } 
 
    }; 
 

 

 
    return function(object, propertiesArray) { 
 
    propertiesArray.forEach(function(propertyList) { 
 
     addProperties(object, propertyList); 
 
    }); 
 
    }; 
 

 
}()); 
 

 

 
const propsToAdd = [ 
 
    ['propA', 'value'], 
 
    ['propB', 'propC', 'propD', 'value'], 
 
    ['propB', 'propF', 'value'] 
 
]; 
 
var object = {}; 
 
addProperties(object, propsToAdd); 
 
console.log(object);

3

由于您的const使用建议ES2015,你可以利用arrow functionsdestructuring assignmentdefault parameters

const nest = ([x, ...xs], o={}) => 
 
    xs.length === 0 ? x : (o[x] = nest(xs,o[x]), o); 
 

 
const nestmany = ([xs, ...yss], o={}) => 
 
    xs === undefined ? o : nestmany(yss, nest(xs,o)); 
 

 
const propsToAdd = [ 
 
    ['propA', 'value1'], 
 
    ['propB', 'propC', 'propD', 'value2'], 
 
    ['propB', 'propF', 'value3'] 
 
]; 
 

 
console.log(nestmany(propsToAdd));