JS数组专题1️⃣ ➖ 数组扁平化
一、什么是数组扁平化
- 扁平化,顾名思义就是减少复杂性装饰,使其事物本身更简洁、简单,突出主题。
 - 数组扁平化,对着上面意思套也知道了,就是将一个复杂的嵌套多层的数组,一层一层的转化为层级较少或者只有一层的数组。
 
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));
番外篇将给大家讲解 lodash 中 flatten 的实现源码,感谢大家阅读!
JS数组专题1️⃣ ➖ 数组扁平化的更多相关文章
- 面试官:JavaScript如何实现数组拍平(扁平化)方法?
		
面试官:JavaScript如何实现数组拍平(扁平化)方法? 1 什么叫数组拍平? 概念很简单,意思是将一个"多维"数组降维,比如: // 原数组是一个"三维" ...
 - JS数组专题2️⃣ ➖ 数组去重
		
距离上次发文,已经有一段时间了,最近工作比较忙,这不眼看快双十一了,就相当于给大家一些福利吧! 一.什么是数组去重 简单说就是把数组中重复的项删除掉,你 GET 到了吗 ?下面我将简单介绍下几种基本的 ...
 - js格式化树形数据(扁平化数据)
		
需求: 1.把如下数据按照parent_id等于id的规则建立父子关系 2.同一层级的数组按照order升序 [ { "id": 1, "name": &quo ...
 - LeetCode:数组专题
		
数组专题 有关数组的一些 leetcode 题,在此做一些记录,不然没几天就忘光光了 二分查找 双指针 滑动窗口 前缀和/差分数组 二分查找 本文内容摘录自公众号labuladong中有关二分查找的文 ...
 - js中数组扁平化处理
		
 - JavaScript数组常用方法解析和深层次js数组扁平化
		
前言 数组作为在开发中常用的集合,除了for循环遍历以外,还有很多内置对象的方法,包括map,以及数组筛选元素filter等. 注:文章结尾处附深层次数组扁平化方法操作. 作为引用数据类型的一种,在处 ...
 - js数组扁平化
		
看到一个有趣的题目: var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; 一个多维 ...
 - JS: 数组扁平化
		
数组扁平化 什么是数组扁平化? 数组扁平化就是将一个多层嵌套的数组 (Arrary) 转化为只有一层. // 多层嵌套 [1, 2, [3, 4]] // 一层 [1, 2, 3, 4] 递归实现 思 ...
 - js技巧-使用reduce实现更简洁的数组对象去重和数组扁平化
		
Array.prototype.reduce()方法介绍: 感性认识reduce累加器: const arr = [1, 2, 3, 4]; const reducer = (accumulator, ...
 
随机推荐
- bash 脚本编程七 将命令输出保存到变量中(转载)
			
转自:http://blog.csdn.net/csfreebird/article/details/7978699 `符号包含的命令执行完后,可以讲其输出结果保存到变量中 #!/bin/bash v ...
 - 5.replace的用法,while循环,continue
			
1.relace s='dadk12' print(s.replace('生活','dd'))==打印返回dadk12,即使没有也不会报错. 2.while continue while循环输出 1 ...
 - C/C++预处理
			
C/C++编译系统编译程序的过程为预处理.编译.链接.预处理器是在程序源文件被编译之前根据预处理指令对程序源文件进行处理的程序.预处理器指令以#号开头标识,末尾不包含分号.预处理命令不是C/C++语言 ...
 - c 浮点科学计数法
			
浮点数 比喻1e1 e后面跟的是10的指数(也就是1的10次方,e表示10次方),f表示浮点数 1e1表示1×10¹,其实就是10 再例如5e2f,表示5×10²,也就是500 =========== ...
 - android动画(1)各种动画属性表,简单代码,xml配置
			
1.动画的属性表 1.1 常用属性 它们可以通过代码setXXX,getXXX,也可在xml中配置. 属性[类型] 功能 备注 Duration[long] 属性为动画持续时间 时间以毫秒为单位 fi ...
 - POM报错Failure to transfer org.apache.maven.plugins:maven-resources-plugin:pom:2.6 from
			
解决方式一: 1.查看.m2\repository\org\apache\maven\plugins\maven-resources-plugin\下maven-resources-plugin- ...
 - django 相关问题
			
和数据库的连接 session的实现 django app开发步骤 python环境准备 数据库安装 model定义 url mapping定义 view定义 template定义 如何查看数据库里的 ...
 - 转 Oracle最新PSU大搜罗
			
Quick Reference to Patch Numbers for Database/GI PSU, SPU(CPU), Bundle Patches and Patchsets (文档 ID ...
 - 转 PHP scandir() 函数
			
实例 列出 images 目录中的文件和目录: <?php $dir = "/images/"; // 以升序排序 - 默认 $a = scandir($dir); // 以 ...
 - Mysql数据类型简介(大概了解)
			
知道有整型,浮点型,定点数类型( DECIMAL(M,D)M是数据总长度,是小数位 ),日期类,字符串类,二进制类型(存图片路径,视频路径一般用BLOG就行了喔)……不会再去查 讲一下几个专有名词: ...