递归添加对象属性

时间:2016-07-14 18:31:54

标签: javascript arrays recursion

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

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的孩子)不能同时是属性的值名称。

如何编写一个递归函数,为对象添加(和嵌套)键/值对?

4 个答案:

答案 0 :(得分:4)

由于您使用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));




答案 1 :(得分: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']
]));
&#13;
&#13;
&#13;

答案 2 :(得分:1)

此处的闭包将遍历要添加到对象的所有属性列表。

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

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

&#13;
&#13;
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);
&#13;
&#13;
&#13;

答案 3 :(得分:0)

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

alert