# 对象-扁平化&反扁平化

# 扁平化

var entryObj = {
	a: {
		b: {
			c: {
				dd: 'abcddd'
			}
		},
		d: {
			xx: 'adxx'
		},
		e: 'ae'
	}
}

function flatten(entryObj) {
    let outputObj = {};
    
    fn(entryObj); // 1、整体问题就是递归函数要解决的问题

    return outputObj;

    // 递归函数
    // 处理 a: {b: {c : {dd: 'xxx'}}} => outputObj['a.b.c.dd'] = 'xxx'
    // 处理 e: 'ae' => outputObj['e'] = 'ae'
    function fn(obj, keyStr = '') {
        for (let key in obj) { // 2、遍历当前对象
            keyStr = keyStr ? keyStr + '.' + key : key;
            if (typeof obj[key] === 'object' && obj[key] !== null) { // 3、若值是对象,则继续遍历,且修改key值
                fn(obj[key], keyStr);
            } else {
                outputObj[keyStr] = obj[key]; // 4、若值非对象,则直接赋值,当前递归结束
            }
        }
    }
}

console.log(JSON.stringify(flatten(entryObj)))
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
34
35
36
37

# 反扁平化

var obj = {
    'a.b.c': 1,
    'a.d': 2,
    'e': 3
}

function transform(entryObj) {
    let outputObj = {};

    // 遍历obj
    for (let key in entryObj) {
        let keys = key.split('.');
        fn(outputObj, keys); // 0、处理entryObj对象的每一个key和value
    }
    return JSON.stringify(outputObj);

    // 递归函数
    // 目标:构建对象
    // 处理 'a.b.c.dd': "abcddd",使得 outputObj = { a: { b: {c : { dd: 'abcddd'}}}}
    // 处理 'xx': "xxxxx",使得 outputObj = { xx: 'abcddd' }
    // outputObj 每次迭代中要构造的对象
    // keys 包含key字符的数组,每次迭代都会减少
    // keyStr 包含key字符的字符串,每次迭代都会增大,吸收keys中的值,最终keys为空时,通过此字段为entryObj提供key
    function fn(outputObj, keys, keyStr='') {
        let currKey = keys.shift();
        keyStr += keyStr ? ('.' + currKey) : currKey; // 1、entryObj key的构建(用来获取value)

        if (keys.length === 0) { // 2、keys为0,说明keys已遍历完成,进行赋值操作
            outputObj[currKey] = entryObj[keyStr]; //
        } else { // 3、keys不为0,说明keys尚未遍历完成,需继续遍历,同时根据遍历的key值构建结构
            if (!outputObj[currKey]) outputObj[currKey] = {};
            fn(outputObj[currKey], keys, keyStr) // 深入嵌套
        }
    }
}

console.log(transform(obj));
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
34
35
36
37
上次更新: 1/5/2022, 9:25:14 AM