Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Rain120 opened this issue Feb 5, 2022 · 1 comment
Open

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

Rain120 opened this issue Feb 5, 2022 · 1 comment

Comments

@Rain120
Copy link
Owner

Rain120 commented Feb 5, 2022

编程题:实现一个对象的 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
Copy link
Owner Author

Rain120 commented Feb 17, 2022

将上述函数结果逆转

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant