Rain120 / Web-Study

日常学习,工作写的笔记
66 stars 108 forks source link

实现一个对象的 flatten 方法(石墨一面) #18

Open Rain120 opened 2 years ago

Rain120 commented 2 years ago

编程题:实现一个对象的 flatten 方法,如下:

const obj = {
a: {
b: 1,
c: 2,
d: {
e: 5
}
},
b: [1, 3, {a: 2, b: 3}],
c: 3
}

flatten(obj){} 结果返回如下

{
"a.b": 1,
"a.c": 2,
"a.d.e": 5,
"b[0]": 1,
"b[1]": 3,
"b[2].a": 2,
"b[2].b": 3,
"c": 3
}
function flatten(obj) {
    var res = {};

    function flat(obj, key) {
        if (obj === null || Object(obj) !== obj) {
            res[key] = obj;
        } else if (Array.isArray(obj)) {
            var len = obj.length;
            if (len < 1) {
                res[key] = [];
                return;
            }

            for (var i = 0; i < len; i++) {
                flat(obj[i], key ? `${key}[${i}]` : key + '');
            }
        } else {
            for (var k in obj) {
                flat(obj[k], key ? `${key}.${k}` : k);
            }
        }
    }

    flat(obj, '');
    return res;
}

var obj = {
    a: {
        b: 1,
        c: 2,
        d: {
            e: 5
        }
    },
    b: [1, 3, {
        a: 2,
        b: 3
    }],
    c: 3
}

flatten(obj)
Rain120 commented 2 years ago

将上述函数结果逆转

var deFlatten = function (entry) {
    const res = {};

    var format = (res, keys, value) => {
        const key = keys.shift();

        if (!keys.length) {
            res[key] = value;
        } else {
            res[key] = res[key] || {};

            format(res[key], keys, value);
        }

    };

    for (const key in entry) {
        const keys = key.split('.');
        format(res, keys, entry[key]);
    }

    for (const key in res) {
        if (/^\w+\[\d+\]$/.test(key)) {
            const k = key.match(/^\w+/)[0];
            const i = key.match(/[\d+]/g).join('');

            res[k] = res[k] || [];
            res[k][i] = res[key];

            delete res[key];
        }
    }

    return res;
}

deFlatten({
    "a.b": 1,
    "a.c": 2,
    "asss.d.e": 5,
    "baa[0]": 1,
    "b[1]": 3,
    "b[2].a": 2,
    "b[20].b": 3,
    "c": 3
})