在 JS 中操作嵌套对象



从这个数组:

objNeeded = [
{onelevel: 'first'},
{
onelevel: 'second',
sublevels: [
{onelevel: 'domain'},
{onelevel: 'subdomain'}
]
},
{
onelevel: 'third',
sublevels: [
{
onelevel: 'fourth',
sublevels: [
{onelevel: 'domain'}
]
}
]
}
];

我需要获取此对象:

objNeeded = {
first: true,
second: {
domain: true,
subdomain: true
},
third: {
fourth: {
domain: true
}
}
};

它可以在数组上具有更多的嵌套对象和更多对象。

我如何使用JavaScript或Typescript获得它?

你可以为此使用递归。由于这对您的用例来说是一个非常具体的问题,因此我不会在这里解释它。不过,我在代码中留下了一些评论。

const objNeeded = [
{onelevel: 'first'},
{
onelevel: 'second',
sublevels: [
{onelevel: 'domain'},
{onelevel: 'subdomain'}
]
},
{
onelevel: 'third',
sublevels: [
{
onelevel: 'fourth',
sublevels: [
{onelevel: 'domain'}
]
}
]
}
];

// from what i understand, the rule ares 
// 1. if the value is a string, it becomes {[key]: true}
// 2. if there is subLevels, we recursive build the subs arrays. 
function recursivalySetSubLevels(elements) {
// this is the output
const output = {}
// we parse every element of the array ( or sub array ) and assign them to the current oneLevels value.
elements.forEach(element => {
// if the element has subLevels,
if(!!element.sublevels) {
// we recursively build the sub object
output[element.onelevel] = recursivalySetSubLevels(element.sublevels);
} else {
// otherwise, we set the key of the oneLevel to true;
output[element.onelevel] = true;
}
});
// and then return the object.
return output;
}

console.log(recursivalySetSubLevels(objNeeded));

你可以使用Array#reduce和递归调用

  1. 用于将数组重新创建为对象格式Array#reduce
  2. 用于查找内部子级别的递归调用

const objNeeded = [{onelevel: 'first'}, { onelevel: 'second', sublevels: [ {onelevel: 'domain'}, {onelevel: 'subdomain'} ] }, { onelevel: 'third', sublevels: [ { onelevel: 'fourth', sublevels: [ {onelevel: 'domain'} ] } ] } ];
const res = objNeeded.reduce((acc, {
onelevel,
sublevels
}) => (acc[onelevel] = sublevels ? recCall(sublevels) : true, acc), {});
function recCall(arr) {
return Object.assign({}, ...arr.map(({
onelevel,
sublevels
}) => ({
[onelevel]: sublevels ? recCall(sublevels) : true
})))
}
console.log(res)

这是一个函数convertObject,可以得到你想要的结果。

for (obj of currentObj)将循环遍历array值并转换对象。

Object.keys(obj)将返回对象中所有key的数组,.includes将检查传入value参数是否存在于数组中。

convertObject内部有一个递归调用,当当前数组对象sublevels时将调用该递归调用。

function convertObject(currentObj) {
// result object
let result = {};
// loop through array values
for (obj of currentObj) {
// check whethere obj has sublevels or not. If it has sublevels then call recursively.
if (Object.keys(obj).includes("sublevels")) {
// retrieve converted object for current object.
result[obj.onelevel] = convertObject(obj.sublevels, result[obj.onelevel]);
} else {
result[obj.onelevel] = true;
}
}
// return result.
return result;
}
let objNeeded = [{onelevel: 'first'}, { onelevel: 'second', sublevels: [ {onelevel: 'domain'}, {onelevel: 'subdomain'} ] }, { onelevel: 'third', sublevels: [ { onelevel: 'fourth', sublevels: [ {onelevel: 'domain'} ] } ] } ];
console.log(convertObject(objNeeded));

这是另一种解决方案:

const objectNeeded = [...];
const reducer = (acc, level) => {
if (level.onelevel) {
acc[level.onelevel] = level.sublevels && level.sublevels.length
? level.sublevels.reduce(reducer, {})
: true;
}
return acc;
};
// Obtain needed object
objectNeeded = objNeeded.reduce(reducer, {});

最新更新