前言
数组的扁平化和去重是面试里面出现频率比较高的两个,所以我们需要重视起来。
本文章是基于死磕36个手写题 写出来的,感兴趣的可以去看一下呀!
数组去重
前端的更新是很快的,所以每一个问题都是有很多的解法,我们需要接受新的东西,但是也不能放过旧的东西。
像数组去重,es5的解法和es6的解法就完全不同,虽然ES6的解法要简单的很多,但是es5的解法我们也要了解呀!
废话不多说,先上代码!
ES5实现:
function unique(arr) {
var res = arr.filter(function(item, index, array) {
return array.indexOf(item) === index
})
return res
}
console.log(unique([1,2,2,3,4,55,55])) //[1,2,3,55]
-
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
-
indexOf() 方法可返回数组中某个指定的元素位置。
该方法将从头到尾地检索数组,看它是否含有对应的元素。开始检索的位置在数组 start 处或数组的开头(没有指定 start 参数时)。如果找到一个 item,则返回 item 的第一次出现的位置。开始位置的索引为 0。
如果在数组中没找到指定元素则返回 -1。
提示:如果你想查找字符串最后出现的位置,请使用 lastIndexOf() 方法。
ES6实现:
var unique = arr => [...new Set(arr)]
console.log(unique([1,2,2,3,4,55,55])) //[1,2,3,55]
- ...是扩展运算符(对象展开符)
扩展运算符( spread )是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
扩展
扩展运算符不仅可以数组去重,还可以合并数组
let a=[1,2,3]
let b=[2,3,4]
let c=[...a,...b]
console.log(c) // [1,2,3,2,3,4]
var unique = arr => [...new Set(arr)]
console.log(unique(c))//[1,2,3,4]
数组扁平化
数组扁平化就是将 [1, [2, [3]]] 这种多层的数组拍平成一层 [1, 2, 3]。使用 Array.prototype.flat 可以直接将多层数组拍平成一层:
[1, [2, [3]]].flat(2) // [1, 2, 3]
-
Array.prototype.flat() 用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。
-
不传参数时,默认“拉平”一层,可以传入一个整数,表示想要“拉平”的层数。 传入 <=0 的整数将返回原数组,不“拉平”
-
Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组
-
如果原数组有空位,Array.prototype.flat() 会跳过空位。
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;
}
flatten 是基于lodash的一种方法。而且lodash中的 flatten 和 flattenDeep 方法都可以实现数组的扁平化。 什么是lodash? Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。
Lodash 遵循 MIT 开源协议发布,并且支持最新的运行环境。 查看各个构件版本的区别并选择一个适合你的版本。
为什么选择 Lodash ?
Lodash 通过降低 array、number、objects、string 等等的使用难度从而让 JavaScript 变得更简单。 Lodash 的模块化方法 非常适用于:
遍历 array、object 和 string
对值进行操作和检测
创建符合功能的函数
通过扩展运算符确实可以避免递归,但是却要使用到循环,如果数组层级过高,循环的消耗也不小,如果连循环也不用呢?
使用字符串,利用正则去掉中括号,实现最简单,而且消耗也最小:
//扁平化数组(不使用循环,使用字符串)
function flatten(arr) {
let str = JSON.stringify(arr).replace(/\[|\]/g, '');
return JSON.parse(Array.of('[' + str + ']')[0]);
}
其实如果没有极端数据的话,使用toString()然后拆分组合也可以实现扁平化,但是不完美,比如以下数据:
let arr = [2, [3.2, [’s,d,w’],’a,b,c,d,e’]];
arr.toString() ==> “2,3.2,s,d,w,a,b,c,d,e”
ES6实现:
function flatten(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
递归其实是存在性能消耗的问题,每次都要重新创建函数,如果不用递归是不是也可以实现呢?
所以ES6就加上了展开运算符
扩展运算符,可以展开数组,每次扒开一层,通过循环可以实现数组扁平化。
总结
数组去重还有数组扁平化我能介绍的也就这么多了,当然还有很多不足点需要我去学习,所以我会继续努力的,欢迎大家多多指教。