Skip to content

Array flatten

题目

写一个函数,实现 Array flatten 扁平化,只减少一个嵌套层级
例如输入 [1, 2, [3, 4, [100, 200], 5], 6] 返回 [1, 2, 3, 4, [100, 200], 5, 6]

解答

  • 遍历数组
  • 如果 item 是数字,则累加
  • 如果 item 是数组,则 forEach 累加其元素

代码参考 array-flatten.ts

ts

/**
 * 数组扁平化,使用 push
 * @param arr arr
 */
export function flatten1(arr: any[]): any[] {
    const res: any[] = []

    arr.forEach(item => {
        if (Array.isArray(item)) {
            item.forEach(n => res.push(n))
        } else {
            res.push(item)
        }
    })

    return res
}

/**
 * 数组扁平化,使用 concat
 * @param arr arr
 */
export function flatten2(arr: any[]): any[] {
    let res: any[] = []

    arr.forEach(item => {
        res = res.concat(item)
    })

    return res
}

连环问:如果想要彻底扁平,忽略所有嵌套层级?

像 lodash flattenDepth ,例如输入 [1, 2, [3, 4, [100, 200], 5], 6] 返回 [1, 2, 3, 4, 100, 200, 5, 6]

最容易想到的解决方案就是递归,代码参考 array-flatten-deep.ts (注意单元测试,有全面的数据类型)

ts

/**
 * 数组深度扁平化,使用 push
 * @param arr arr
 */
export function flattenDeep1(arr: any[]): any[] {
    const res: any[] = []

    arr.forEach(item => {
        if (Array.isArray(item)) {
            const flatItem = flattenDeep1(item) // 递归
            flatItem.forEach(n => res.push(n))
        } else {
            res.push(item)
        }
    })

    return res
}

/**
 * 数组深度扁平化,使用 concat
 * @param arr arr
 */
export function flattenDeep2(arr: any[]): any[] {
    let res: any[] = []

    arr.forEach(item => {
        if (Array.isArray(item)) {
            const flatItem = flattenDeep2(item) // 递归
            res = res.concat(flatItem)
        } else {
            res = res.concat(item)
        }
    })

    return res
}

还有一种 hack 的方式 toString —— 但遇到引用类型的 item 就不行了。

js
const nums = [1, 2, [3, 4, [100, 200], 5], 6]
nums.toString() // '1,2,3,4,100,200,5,6'

// 但万一数组元素是 {x: 100} 等引用类型,就不可以了

Released under the MIT License.