使用点表示法动态创建具有路径数组的对象

时间:2018-04-04 17:45:49

标签: javascript arrays json object

我想知道是否可以用点表示法动态生成带有字符串数组的对象。我想从CSV文件动态构建JSON对象。目标是将CSV构建为JSON,然后过滤属性并创建一个新的JSON对象。

所以我想传递类似的内容..

var obj = {};
var keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer'];

最终结果将是这样的......

obj = {
 meta: {
 },
 logos: {
 },
 specs: {
    engine: {
       hp: {
       }
    }
 }
}

这是主要功能

function addObjectsByKey(obj, keyArray) {

    for (var key in keyArray) {

        // If keyword is not in object notation
        if (!(keyArray[key].match(/\./))) {

            // If the object property is not set, set it
            if (!(obj[keyArray[key]])) {

                obj[keyArray[key]] = {};

            }

        } else {

            // Split array element (in dot notation) into an array of strings
           // These strings will be object properties
            var pathAsArray = keyArray[key].split('.');
            var path = null;

            for (var k in pathAsArray) {
                if (path == null) {
                    obj[pathAsArray[k]] = {};
                    path = pathAsArray[k];
                } else {
                    obj[path][pathAsArray[k]] = {};
                    path += '.' + pathAsArray[k];
                }
            }
            // throw Error('end');

        }

    }
    // return obj;
}

2 个答案:

答案 0 :(得分:2)

您可以使用forEach循环,在内部可以拆分.上的每个元素,然后使用reduce方法构建嵌套对象。

var keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer'];
const result = {}
keyArray.forEach(key => {
  // Loop array of keys
  // Split each key with . and use reduce on that 
  // In each iteration of reduce return r[e] which is going to be value if property exists
  // or new object if it doesn't
  // This way you can go to any object depth as long as keys match existing keys in object.
  key.split('.').reduce((r, e) => r[e] = (r[e] || {}), result)
})

console.log(result)

这是使用for循环的另一种方法,它将返回相同的结果。

var keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer' ];
const result = {}

for(var i = 0; i < keyArray.length; i++) {
  const keys = keyArray[i].split('.');
  let ref = result;
  for(var j = 0; j < keys.length; j++) {
    const key = keys[j];
    if(!ref[key]) ref[key] = {}
    ref = ref[key]
  }
}

console.log(result)

答案 1 :(得分:1)

您可以使用函数reduce和嵌套forEach来构建路径。

  • 第一个reduce将累积嵌套操作。
  • 嵌套forEach将根据以点分隔的当前路径构建对象及其子对象。

let keyArray = ['meta', 'logos', 'warranty', 'specs', 'specs.engine', 'specs.engine.hp', 'specs.engine.rpm', 'specs.engine.manufacturer'],
    newObj = keyArray.reduce((accum, path) => {
      let previous = accum;
      path.split('.').forEach(key => {
        if (previous[key]) previous = previous[key];
        else previous = previous[key] = {};
      });
      
      return accum;
    }, {});

console.log(newObj);
.as-console-wrapper { max-height: 100% !important; top: 0; }