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

数组或对象的扁平化处理 #21

Open
xuexueq opened this issue Oct 9, 2018 · 0 comments
Open

数组或对象的扁平化处理 #21

xuexueq opened this issue Oct 9, 2018 · 0 comments
Labels
Javascript Javascript

Comments

@xuexueq
Copy link
Owner

xuexueq commented Oct 9, 2018

数组的扁平化

1. 递归

function flatten(arr) {
    let result = [];
    arr.map((item) => {
        if(item.constructor == Array) {
            result = result.concat(flatten(item)); // concat 不改变原数组
            // result.push(...flatten(item));
        } else {
            result.push(item);
        }
    });
    return result;
}

2. Array.reduce()

function flatten(arr) {
    return arr.reduce((pre, next) => {
        return pre.concat(next.constructor == Array ? flatten(next) : next);
    }, []);
}

3. es6中的扩展操作符

[].concat(...arr),每次只会扁平化一层, so 判断该数组中有几层数组来一层一层的进行扁平。

let arr = [1,3,[3,6,[7]]];
[].concat(...arr) // [1,3,3,6,[7]]
function flatten(arr) {
    while(arr.some(item => item.constructor === Array)) {
        arr = [].concat(...arr); // 
    }
    return arr;
}

4. 使用 toString()

只对数组的元素都是数字时有效 valueOf()
如果数组是 [1, '1', 2, '2'] 的话,这种方法就会产生错误的结果。

[1,3,[3,6,[7]]].toString(); // "1,3,3,6,7"
[1,3,[3,6,[7]]].valueOf(); // [1,3,[3,6,[7]]]
function flatten(arr) {
    return arr.toString().split(',').map(item => +item);
}

对象的扁平化

function flatten(input) {
    let result = {}; // 结果是一个对象
    function process(key, value) {
        if(Object(value) !== value) { // 不是对象也不是数组(引用类型) 即基本类型 注意:要严格不相等
            if(key) result[key] = value;
        } else if(value.constructor === Array) {
            for(let i = 0,len = value.length; i < len; i++) {
                process(`${key}[${i}]`, value[i]);
            }
            if(key && value.length === 0) result[key] = [];
        } else {
            let isObjectEmpty = true;
            for(let item in value) {
                isObjectEmpty = false;
                process(key ? `${key}.${item}` : `${item}`, value[item]); // 判断是否有key来决定带不带. (对于第一次调用process有用)
            }
            if(isObjectEmpty && key) result[key] = {};
        }
    }
    process('', input);
    return result;
}

// 测试
const input = {
    a: 1,
    b: [1, 2, { c: true },
        [3]
    ],
    d: { e: 2, f: 3 },
    g: null,
    h: [],
    i: {}
}
@xuexueq xuexueq added the Javascript Javascript label Oct 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Javascript Javascript
Projects
None yet
Development

No branches or pull requests

1 participant