前两天看到了一道前端面试题,《第11题:将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组》,题目倒是没有多难,但是看了其中一个答案,感觉思路满满啊。

  关于数组扁平化,前面写过一篇文章,在这里又看到了一个新的方法,在Array.prototype对象当中提供了一个方法:flat(depth)。  

  

  唯一的问题是,该方法目前虽然在部分浏览器当中能用,但是他还没有成为标准方法。他支持一个参数,指定嵌套数组中的结构深度,默认值为1。也就是扁平化多少层数组。

  关于去重,在ES6当中,新增了一种语法结构Set,元素天生就唯一。

Set对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。

  那么就利用flat和Set实现一种最简单的解法吧。

[...new Set(arr.flat(Infinity))].sort((a, b) => a - b)

  是不是最精简的答案了?利用flat,Set数据结构还有一些写法,可以参考上述链接的文章,自行理解。

  我这里想说的是,我在上面看到的扁平化数组的方法:利用toString(),说出来之后,可能不值得一提,但是能够想到这个方法,我反正觉得挺厉害的。

  这个方法是有一定的局限性的:数组元素只能是基本类型的数字或字符串,在这个面试题当中,当然是完美的解决方案之一。

arr.toString()

  简单直接,不是吗?

  那么扁平化之后,就是去重,和排序了。

  但是这里将他扁平化成为字符串了,那么自然想到字符串当中有一个方法split,必须注意的是split之后的数组元素也是字符串,所以还需要将元素转换为数字。

arr.toString().split(",").map(Number)

  当然这里转化为数字的方法也用到了ES6的方法:map。

  如果想完全避免ES6, 就只剩下华山一条道了:for循环。既然都循环了,当然可以顺带做一下数组去重了,关于数组去重,我在前面写过两篇文章,这里不再赘述。这里利用的是hash去重的方法,正好可以对前面写的hash去重稍作优化。

// 1、扁平化数组
var flatArr = arr.toString().split(",");
// 2、去重
var hash = {};
for (var i = 0, len = flatArr.length; i < len; i++) {
    hash[flatArr[i]] = "abc"
}
flatArr = [];
// 3、将元素字符串转化为数字、遍历hash并不能保证输出顺序
for (var i in hash) {
    flatArr.push(+i)
}

  至于说将字符串转换为数字,是在for循环体内和去重一起做,还是去重之后,提取key值的时候再做,没有什么本质上的区别。我这里是在去重之后,提取hash对象的key值的时候,利用一元运算符+,进行的类型转换。

  到这一步之后,就好办了,就只剩下排序了。排序的方法还是利用的数组方法sort。

  那么整道题目的过程如下: 

// 1、扁平化数组
var flatArr = arr.toString().split(",");
// 2、去重
var hash = {};
for (var i = 0, len = flatArr.length; i < len; i++) {
    hash[flatArr[i]] = "abc"
}
flatArr = [];
// 3、将元素字符串转化为数字、遍历hash并不能保证输出顺序
for (var i in hash) {
    flatArr.push(+i)
}
// 4、排序
flatArr = flatArr.sort(function(a, b) {
    return a - b
})

  此时,flatArr就是最后答案,进行了扁平化,去重,排序。

  

  

  

 

posted on 2019-02-18 11:01  烛火星光  阅读(930)  评论(0编辑  收藏  举报