极客时间返利平台,你可以在上边通过山月的链接购买课程,并添加我的微信 (shanyue94) 领取返现。
每天晚上九点 B站讲解前端工程化直播,并解答相关问题。

# 实现一个数组扁平化的函数 flatten

更多描述

flatten 模拟 Array.prototype.flat 实现,默认展开一层,可传递参数用以展开多层

// [1, 2, 3, 4, [5, 6]]
flatten([1, 2, 3, [4, [5, 6]]]);

// [1, 2, 3, 4, 5, 6]
flatten([1, 2, 3, [4, [5, 6]]], 2);

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 451 (opens new window)

在 ES2019 之前,可通过 reduce + concat 实现,由于 Array.prototype.concat 既可以连接数组又可以连接单项,十分巧妙

const flatten = (list) => list.reduce((a, b) => a.concat(b), []);

一个更简单的实现方式是 Array.prototype.concat... 运算符

const flatten = (list) => [].concat(...list);

如果要求深层数组打平,则如下实现

const flatten = (list) =>
  list.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);

如果要求如同原生 API Array.prototype.flat 一致的 API,可传入可扁平的深度。代码可见 【Q443】实现一个数组扁平化的函数 flatten (opens new window)

function flatten(list, depth = 1) {
  if (depth === 0) return list;
  return list.reduce(
    (a, b) => a.concat(Array.isArray(b) ? flatten(b, depth - 1) : b),
    []
  );
}

在 ES2019 之后,可通过 Array.prototype.flat 直接实现!

您好作者,您的实现方式最多只能降维一层深度。

const flatten = (list) =>
  list.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);

不仅如此,ES2019 的 flat 还支持传入**depth**来降维指定的深度。

@reveriesMeng 好的

const flatten = (arr, d = 1) => d > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatten(val, d - 1) : val), []) : arr.slice()
function flat(array, depth = Number.MAX_VALUE) {
  let result = [...array];
  while (result.some((i) => Array.isArray(i) && depth > 0)) {
    // 注意concat方法的参数valueN,即可是数值也可以是数组,当时数组时存在隐形的展开操作
    // concat方法不改变原数组,返回一个新数组
    result = [].concat(...result);
    depth--;
  }
  return result;
}

@haotie1990 原生 API 默认是 1,当然这个题目我也没有规定,不过 depth 用 MAX_SAFE_INTEGER 或者 Infinity 好一些?

而且该 API 也不涉及对数组自身的操作,应该无需 [...array]

function flatten(arr) {
return arr.reduce((result, item)=> { return result.concat(Array.isArray(item) ? flatten(item) : item); }, []); }

function flatten(arr) { return arr.toString().split(',').map(function(item) { return Number(item); }) }

Last Updated: 11/27/2021, 10:11:48 AM