根据数组将数组转换为具有嵌套属性的对象

时间:2017-09-23 11:28:04

标签: javascript node.js javascript-objects

我有以下几个数组:

[ 'businessOpenAccount', 'accountSettings1.page.js' ]
[ 'businessOpenAccount', 'accountSettings2.page.js' ]
[ 'mainTest', 'test', 'test1.page.js' ]
[ 'mainTest', 'test', 'test2.page.js' ]

我的预期结果是以这种方式拥有一个对象:

{
  businessOpenAccount: {
    'accountSettings1.page.js': {},
    'accountSettings2.page.js': {}
  },
  mainTest: {
    test: {
      'test1.page.js': {},
      'test2.page.js': {}
    }
  }
}

所以实际上我想解析数组并构建一个嵌套对象从它们返回,但是一定要检查一个属性是否已经存在(因为从前一个数组中定义)我不会覆盖它,但是只需在其中添加新的嵌套属性,遵循正确的嵌套顺序。

我尝试使用reducereduceRight和简单forEach / for循环的方法很少,但我仍然无法真正实现我想要的解决方案。

请提示?

这是我到目前为止最好的方法,但是我覆盖了在多个数组上循环的属性(带有单个数组的示例):



const relevantFilePath = ['businessOpenAccount', 'accountSettings.page.js'];
let obj = {};
relevantFilePath.forEach((el, ind) => {
  if (ind === 0) {
    obj[el] = {};
    previousEl = obj[el];
  } else {
    previousEl[el] = {};
    previousEl = previousEl[el];
  }
});
console.log(obj);




2 个答案:

答案 0 :(得分:2)

您可以迭代给定数据并减少对象并使用拆分值获取最后一项。



var data = [['businessOpenAccount', 'accountSettings1.page.js'], ['businessOpenAccount', 'accountSettings2.page.js'], ['mainTest', 'test', 'test1.page.js'], ['mainTest', 'test', 'test2.page.js']],
    object = {};
    
data.forEach(function (a) {
    var last = a.pop().split('.')[0];
    
    a.reduce(function (o, k) {
        return o[k] = o[k] || {};
    }, object)[last] = '';
});

console.log(object);

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




ES6,不改变原始数据



var data = [['businessOpenAccount', 'accountSettings1.page.js'], ['businessOpenAccount', 'accountSettings2.page.js'], ['mainTest', 'test', 'test1.page.js'], ['mainTest', 'test', 'test2.page.js']],
    object = {};
    
data.forEach(function (a) {
     var temp = a.slice(),
         last = temp.pop().split('.')[0];
    
    temp.reduce((o, k) => o[k] = o[k] || {}, object)[last] = '';
});

console.log(object);

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




答案 1 :(得分:0)

一种递归解决方案,适用于任何具有无限深度的子数组。



const a = [
    ['businessOpenAccount', 'accountSettings1.page.js'], 
    ['businessOpenAccount', 'accountSettings2.page.js'], 
    [ 'businessOpenAccount', 'test1', 
        [
            ['test2', 'test2.settings.page.js', 
                [
                     ['test2', 'test2.settings.page.js'],
                     ['test3', 'test3.settings.page.js'],
                ], 
                'test4',
            ],
            ['test3', 'test3.settings.page.js'],
        ]
    ],
    ['mainTest', 'test', 'test1.page.js'], 
    ['mainTest', 'test', 'test2.page.js'],
];

const result = {};

const traverse = (result, arr) => {
    let firstEl = arr.shift();
    if (firstEl instanceof Array) {
        if (arr.length >= 1) {
            traverseTop(result, firstEl);
            return traverse(result, arr);
        } 
        return traverseTop(result, firstEl);
    }
    firstEl = firstEl.split('.')[0];
    result[firstEl] = arr.length >= 1 ? (result[firstEl] || {}) : '';
    if (arr.length >= 1) {
        return traverse(result[firstEl], arr);
    }
    return;
};

const traverseTop = (result, arr) => {
    arr.forEach((subArr) => {
        const firstEl = subArr.shift().split('.')[0];
        result[firstEl] = result[firstEl] || {};
        traverse(result[firstEl], subArr)
    });
    return result;
};

console.log(traverseTop(result, a));