0%

JS Tree 树状数据 Object Array互转

问题

需要这两个格式的数据,能够互相转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 什么的,我知道这东西也大概用过,但说来惭愧,不会。

这个循环递归的方法有个大佬说还会爆栈,内存溢出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 数组转对象
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的回答
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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']) }),
{}
);