问题
需要这两个格式的数据,能够互相转换。
let obj = {
a: 123,
b: { a: 456, b: 789, c: { d: 111, e: 222 } },
f: 11,
};
let arr = [
{ name: 'a', value: 123 },
{
name: 'b',
value: undefined,
children: [
{ name: 'a', value: 456 },
{ name: 'b', value: 789 },
{
name: 'c',
value: undefined,
children: [
{ name: 'd', value: 111 },
{ name: 'e', value: 222 },
],
},
],
},
{ name: 'f', value: 111 },
];
注意,对象名称为 name,对象的值不一定是 value,对象的值遇见 children 的时候,是个对象。
解决问题
我用的是循环递归,因为我太菜了
群里说的有 BFS 什么的,我知道这东西也大概用过,但说来惭愧,不会。
这个循环递归的方法有个大佬说还会爆栈,内存溢出。
// 数组转对象
function arrayToObject(params) {
let obj = {};
for (let index = 0; index < params.length; index++) {
const element = params[index];
const { name, value } = element;
if ('children' in element) {
obj[name] = arrayToObject(element.children);
} else {
obj[name] = value;
}
}
return obj;
}
// 对象转数组
function ObjectToArray(params) {
let array = [];
for (const key in params) {
if (Object.hasOwnProperty.call(params, key)) {
const element = params[key];
if (Object.prototype.toString.call(element) === '[object Object]') {
array.push({ name: key, value: undefined, children: ObjectToArray(element) });
} else {
array.push({ name: key, value: element });
}
}
}
return array;
}
console.log(arrayToObject(arr));
console.log(ObjectToArray(obj));
求更好的解法
目前没有求到更好的解法,我先把解法和代码贴出来。
- 2021 年 5 月 17 日补充群友德巨 Kio 的回答
const o2a = (o) =>
Object
.entries(o)
.map(([name, value]) =>
typeof value !== 'object'
? { name, value }
: { name, value: undefined, children: o2a(value) }
);
const a2o = (a) =>
a.reduce(
(o, i) => ({ ...o, [i['name']]: i['value'] ?? a2o(i['children']) }),
{}
);