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} 等引用类型,就不可以了