js 数组扁平化, 多方法实现

397 阅读2分钟

js 数组扁平化, 多方法实现

// 全局变量 arr
const arr = [1, [2, [3, [4, 5]]], 6, 7, [8, 9]]

方法一 使用 Array.prototype.flat()


/**
 * 使用 Array.prototype.flat()
 * flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
 * 
 * var newArr = arr.flat([depth])、
 * 
 * 参数 depth 可选
 * 指定要提取嵌套数组的结构深度,默认值为 1。
 * 
 * 返回值
 * 一个包含将数组与子数组中所有元素的新数组。
 * 
 */

const res1 = arr.flat(Infinity)
console.log(res1) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

方法二 使用 正则

/**
 * 使用 正则
 * 先使用JSON.stringify(arr)将数组转换为json字符串,在使用字符串方法 .replace(参数1:正则表达式 /\[|\]/g, 参数二: '' 替换为空字符串 ) 在使用字符串的 split(参数1: ',' 以逗号为分割符)方法,
 * 
 * 弊端
 * 数据类型都会变为字符串
 * 
 */

const res2 = JSON.stringify(arr).replace(/\[|\]/g, '').split(',')
console.log(res2) // ['1', '2', '3', '4', '5', '6', '7', '8', '9']

方法三 使用 升级版正则

/** 
 * 使用 升级版正则
 * 使用 JSON.parse() 解析JSON.stringify(arr).splace(/\[|\]/g, '')的字符串结果在前后分别加上 字符窜 '['']'
 * JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']') 这样方法二的 弊端就不存在了
 * 
 */

const res3 = JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']')
console.log(res3) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

方法四 使用 Array.prototype.reduce()

/**
 * 使用 Array.prototype.reduce()
 * reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
 * 
 * 函数参数
 * 
 * callback
 *  Accumulator (acc) (累计器)
 *  Current Value (cur) (当前值)
 *  Current Index (idx) (当前索引)
 *  Source Array (src) (源数组)
 *  您的 reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
 * 
 * initialValue 可选
 *  作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。 
 * 
 * 使用reduce方法, 在callback函数体内,用参数1 累加器(累加器的初始值为 []空数组),然后使用数组 concat()合并方法,concat的参数 使用Array.isArray() 判断当前值是否为数组,返回值为 true | false, 返回值为 true 再次调用  flatten(参数是当前值 cur) 返回值为 false 直接合并数组
 * 
 */

const flatten = (data) => {
  return data.reduce((acc, cur) => {
    return acc.concat(Array.isArray(cur) ? flatten(cur) : cur)
  }, [])
}

const res4 = flatten(arr)
console.log(res4) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

方法五 使用 递归函数

/**
 * 使用 递归函数
 * 
 * 解析
 * flatten2(arr) 函数体内,使用for循环遍历参数 arr,循环体内 用Array.isArray(data[i]) 是否为数组,返回值true,继续递归调用 flatten2(data[i]), 返回值false, res5.push(data[i]), 知道循环完毕 
 * 
 */

const res5 = []
const flatten2 = (data) => {
  for (let i = 0; i < data.length; i++) {
    if (Array.isArray(data[i])) {
      flatten2(data[i])
    } else {
      res5.push(data[i])
    }
  }
}
flatten2(arr)
console.log(res5) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]