从这个数组:
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
和递归调用
- 用于将数组重新创建为对象格式
Array#reduce
- 用于查找内部子级别的递归调用
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, {});