数组扁平化的方法

142 阅读2分钟

数组扁平化的方法

数组扁平化,简单说就是将数组进行降维

库函数flat

数组对象包含一个扁平化的方法,推荐使用

Array.flat();

传入控制展开的层数

Array.flat(Infinity); // 默认为1只展开一层,传入Infinity全部展开

递归遍历

function flatten (array) {
    let result = [];
    for (const item of array) {
        if (Array.isArray(item)) { // 若元素为数组,递归展开并合并结果
            result = result.concat(flatten(item));
        } else {
            result.push(item);
        }
    }
    return result;
}

进一步思考,模仿库函数,添加一个表示展开几层的参数

function flatten (array, number) {
    number = number !== undefined ? number : 1; // 未传入时默认为1,只展开一层
    let result = [];
    for (const item of array) {
        if (Array.isArray(item) && number > 0) {
            result = result.concat(flatten(item, number - 1));
        } else {
            result.push(item);
        }
    }
    return result;
}

reduce函数进行递归

function flatten (array) {
    return array.reduce((pre, curr) => {
       return pre.concat(Array.isArray(curr) ? flatten(curr) : curr);
    }, []); // 传入初值,使reduce从索引为0的项开始执行而非索引为1项
}

添加控制参数

function flatten (array, number) {
    number = number !== undefined ? number : 1;
    return array.reduce((pre, curr) => {
        return pre.concat(Array.isArray(curr) && number > 0 ? flatten(curr, number - 1) : [curr]); // 需要注意curr项应变为数组,否则concat会展开一层
    }, []);
}

findIndex循环展开每一项

function flatten (array) {
    while (array.findIndex(item => Array.isArray(item)) >= 0) {
        array = [].concat(...array);
    }
    return array;
}

添加层数控制

function flatten (array, number) {
    number = number !== undefined ? number : 1;
    while (array.findIndex(item => Array.isArray(item)) >= 0 && number > 0) {
        array = [].concat(...array);
        number--;
    }
    return array;
}

使用栈和展开运算符

直接实现包含控制条件的方法

function flatten (array, number) {
    number = number !== undefined ? number : 1;
    let result = [];
    const stack = [].concat(array);
    while (stack.length > 0) {
        const item = stack.pop();
        if (Array.isArray(item) && number > 0) {
            stack.push(...item);
            number--;
        } else {
            item !== undefined && result.unshift(item);
        }
    }
    return result;
}

数组强制类型转化

更适合string类型的数组

function flatten (array) {
    return array.toString().split(",").map(item => item); // 注意Number数组需要再次转换类型
}

使用JSON函数和正则

function flatten (array) {
    let result = JSON.stringify(array);
    result = result.replace(/(\[|\])/g, ""); // 正则去除所有[和]符号
    result = `[${result}]`;
    return JSON.parse(result);
}

总结

综上,实际开发中能直接使用库函数就用库函数,不止代码更加简洁,而且还能保证正确性;其余几种方式只是作为了解扁平化以及熟悉数组操作的方式,以及在库函数不满足的情况(如:扁平的同时对每项进行一些处理)下使用。

以及,对于最后两种实现方式,目前暂时还未想到比较优雅的控制层数的方式,还有进步空间...