专题缘由
该专题主要是讲解我们在面试的时候碰到一些JS
的手写题, 确实这种手写题还是比较恶心的。有些时候好不容易把题目写出来了,突然面试官冷不丁来一句有没有更优的解法,直接让我们僵在原地。为了解决兄弟们的这些困扰,这个专题于是就诞生啦。我们会将一些常见的不是最优解的答案作为对比,方便大家更好理解。
正文
这篇上主要讲的是常考的数组常见题。之后会中下两篇分别讲下数组排序以及数组原型链相关的考题。
数组去重(难度:🌟)
先来一个简单的,对,就是数组去重。给定一个数组,去除掉数组中重复的数据。
有些年轻小伙子不讲武德
,刚毕业,20来岁,上来就用两层For
循环开开心心地写着,作为一个面试官,很多时候我想打断他, 但是又于心不忍,破坏他写代码时专注的气氛。最后,作为面试官我们来了一句
你觉得还有没有更好的解法呢?
非最优解
function unique(arr){ for(let i=0; i<arr.length; i++){ for(let j=i+1; j<arr.length; j++){ if(arr[i] === arr[j]){ arr.splice(j,1); j--; } } } return arr; } const arr = [1,1,'true','true',true,true,15,15,false,false]; console.log(unique(arr)) // [ 1, 'true', true, 15, false ]
最优解
我将最优解分为了两类,一类是ES5,一类是ES6的。因为有些浏览器版本还不支持ES6,所以要做个兼容。
ES5
使用filter
实现
function unique(arr) { return arr.filter(function(item, index, array) { return arr.indexOf(item) === index }) } const arr = [1,1,'true','true',true,true,15,15,false,false]; console.log(unique(arr)) // [ 1, 'true', true, 15, false ]
ES6
使用Set
数据结构实现
const unique = arr => [new Set(arr)] const arr = [1,1,'true','true',true,true,15,15,false,false]; console.log(unique(arr)) // [ 1, 'true', true, 15, false ]
数组扁平化(难度:🌟🌟)
数组扁平化就是把多维数组转化成一维数组。举个🌰:
['a',['b',['c']]]
经过数组扁平化后变为['a','b','c']
有很多年轻人见到这题后,就开始了长久的静坐,咳咳。当然也不乏有些天资聪颖之辈,上来就花了10秒钟
解决了这个问题, 他们说ES6
中有flat
方法。
let arr = ['a',['b',['c']]]; console.log(arr.flat(2)); // [ 'a', 'b', 'c' ]
是的 flat
方法确实能将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
正在这些年轻人洋洋得意的时候,面试官突然来了一句
小伙子,不好意思,我没把问题表述清楚,我希望的是你能把这个flat方法实现一下。
接下来便是长久的静默........
最优解
好像也没有什么非最优解,毕竟能做出来就很不错啦。
ES5
通过递归的方式将所有是数组的子元素进行遍历。
const flatten = (arr) => { let res = []; for (let i = 0; i < arr.length; i++) { if (Array.isArray(arr[i])) { res = res.concat(flatten(arr[i])); } else { res.push(arr[i]); } } return res; }; let arr = ['a',['b',['c']]]; console.log(flatten(arr)); // [ 'a', 'b', 'c' ]
ES6
这个做法颇为巧妙,通过while(arr.some((item) => Array.isArray(item)))
这段代码,如果数组里还有内嵌数组,那么这个条件一直为真,会一直执行下去,知道所有的元素都不是数组为止才会推出循环。
const flatten = (arr) => { while (arr.some((item) => Array.isArray(item))) { arr = [].concat(arr); } return arr; }; let arr = ["a", ["b", ["c"]]]; console.log(flatten(arr)); // [ 'a', 'b', 'c' ]