Rain120/Web-Study

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

Rain120 opened this issue · 1 comments

编程题:实现一个对象的 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)

将上述函数结果逆转

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
})