根据数组将数组转换为具有嵌套属性的对象
我有几个数组如下:
[ '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': {} } } }
所以实际上我想parsing数组,并构build一个嵌套的对象从它们返回,但一定要检查,如果一个属性已经存在(因为从以前的数组定义)我不会覆盖它,但只是添加新的嵌套属性,尊重嵌套的正确顺序。
我尝试了使用reduce
, reduceRight
和简单forEach
/ for
循环的方法,但是我仍然无法真正实现我想要的解决scheme。
请提供任何提示?
这是我迄今为止最好的方法,但是我重写了循环多个数组的属性(使用单个数组的示例):
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);
你可以迭代给定的数据,减less对象,并采取分割值的最后一个项目。
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; }
一个recursion的解决scheme,可用于任何深度无限的子arrays。
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));