资讯专栏INFORMATION COLUMN

JS数组专题1️⃣ ➖ 数组扁平化

lieeps / 2550人阅读

一、什么是数组扁平化

扁平化,顾名思义就是减少复杂性装饰,使其事物本身更简洁、简单,突出主题。

数组扁平化,对着上面意思套也知道了,就是将一个复杂的嵌套多层的数组,一层一层的转化为层级较少或者只有一层的数组。

Ps: flatten 可以使数组扁平化,效果就会如下:

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr)); // [1, 2, 3, 4]
从中可以看出,使用 flatten 处理后的数组只有一层,下面我们来试着实现一下。
二、简单实现 2.1 普通递归

这是最容易想到的方法,简单,清晰!

/* ES6 */
const flatten = (arr) => {
  let result = [];
  arr.forEach((item, i, arr) => {
    if (Array.isArray(item)) {
      result = result.concat(flatten(item));
    } else {
      result.push(arr[i])
    }
  })
  return result;
};

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
/* ES5 */
function flatten(arr) {
  var result = [];
  for (var i = 0, len = arr.length; i < len; i++) {
    if (Array.isArray(arr[i])) {
      result = result.concat(flatten(arr[i]))
    }
    else {
      result.push(arr[i])
    }
  }
  return result;
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
2.2 toString()

该方法是利用 toString 把数组变成以逗号分隔的字符串,然后遍历数组把每一项再变回原来的类型。

先来看下 toString 是怎么把数组变成字符串的

[1, [2, 3, [4]]].toString()
// "1,2,3,4"

完整的展示

/* ES6 */
const flatten = (arr) => arr.toString().split(",").map((item) => +item);

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
/* ES5 */
function flatten(arr) {
  return arr.toString().split(",").map(function(item){
    return +item;
  });
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
这种方法使用的场景却非常有限,必须数组中元素全部都是 Number
也可以全部都为 String,具体实现大家自己体会。
2.3 [].concat.apply + some

利用 arr.some 判断当数组中还有数组的话,循环调用 flatten 扁平函数(利用 [].concat.apply扁平), 用 concat 连接,最终返回 arr;

/* ES6 */
const flatten = (arr) => {
  while (arr.some(item => Array.isArray(item))){
    arr = [].concat.apply([], arr);
  }
  return arr;
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
/* ES5 */
/**
* 封装Array.some
* @param {function} callback    - 回调函数
* @param {any}      currentThis - 回调函数中this指向
*/
Array.prototype.some = function (callback, currentThis){
  let context = this;
  let flag = false;
  currentThis = currentThis || this;
  for (var i = 0, len = context.length; i < len; i++) {
    const res = callback.call(currentThis, context[i], i, context);
    if (res) {
      flag = true;
    } else if (!flag) {
      flag = false;
    }
  }
  return flag;
}

function flatten(arr){
  while(arr.some(item => Array.isArray(item))){
    arr = [].concat.apply([], arr);
  }
  return arr;
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
2.4 reduce

reduce 本身就是一个迭代循环器,通常用于累加,所以根据这一特点有以下:

function flatten(arr){
  return arr.reduce(function(prev, cur){
    return prev.concat(Array.isArray(cur) ? flatten(cur) : cur)
  }, [])
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));
2.5 ES6 中的 解构运算符 ...

... 每次只能展开最外层的数组,被 [].concat 后,arr 就扁平化一次。

function flatten(arr){
  while(arr.some(item => Array.isArray(item))){
    arr = [].concat(...arr);
  }
  return arr;
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));

番外篇将给大家讲解 lodashflatten 的实现源码,感谢大家阅读!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96617.html

相关文章

  • JS数组专题2数组去重

    距离上次发文,已经有一段时间了,最近工作比较忙,这不眼看快双十一了,就相当于给大家一些福利吧! showImg(https://segmentfault.com/img/remote/1460000016538082?w=250&h=250); 一、什么是数组去重 简单说就是把数组中重复的项删除掉,你 GET 到了吗 ?下面我将简单介绍下几种基本的方法及其优缺点。 二、方法汇总 两层循环 无相同...

    tunny 评论0 收藏0
  • ⚡每日肥学⚡——算法&amp;面试题3

    每日肥学 导读?算法题一点点思路源码和解析 ?面试题特别介绍 导读 小伙伴们新的学期又要开始了,您是否已经做好了冲刺的准备了呢?如果您想在这个学期收获的比别人更多我建议给肥肥点个关注。我们一起来增长知识,无论你是考研还是找工作或者是要加薪。这里都是一个不错的选择。让我们红尘作伴,一起肥学!!! ?算法题 实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列...

    biaoxiaoduan 评论0 收藏0
  • JavaScript数组函数

    摘要:如果有两个参数,该方法返回起始和结束位置之间的项,但不包括结束位置的项。删除删除任意数量的项,只需指定两个参数要删除的第一项的位置和要删除的项数。例如会删除数组中的前两项。和这两个方法都接收两个参数要查找的项和可选的表示查找起点位置的索引。 下面总结了一些JavaScript中常用的数组操作方法。验证是不是数组用 arr instanceof Array 或者Array.isArray...

    notebin 评论0 收藏0

发表评论

0条评论

lieeps

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<