JS如何优雅的处理扁平化和去重 – 一道面试题引发的思考

一道面试题引发的思考

面试

前几天学员群里面在讨论面试题。题目如下,要求要用尽量少的代码进行处理尽量不要超过五行。

// 输入数据
const input =  [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]
// 输出数据
expect =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

其实这个就是一个比较基础的javascript权威指南算法题。 需要处理扁平化、排javascriptdownload序、去重三个问题,而且最好是能够利用函数式的写法这样代码就会简洁一些。

学霸答案

const ary = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10]
console.log('ary', [... new Set(ary.flat(Infinity))].sort((a, b) => a - b))

解析一下:

  • 扁平化使用ary的flat方法
  • Set方式去重
  • 排序sjavascript是干什么的ort常规操作
  • 最后用...展开为数组 整个过程非常流畅,确实是学霸答案。感觉这些常算法设计与分析用的函数运用的想自己的手脚一般自如。

算法算法设计与分析化的实现方法

1. flat函数

扁平化最简洁的算法的时间复杂度取决于方法就是flat

// depth代表展开深度默认值1
// Infinity为无限深度
const newArray = arr.flat([depth]);

2. 循环+递算法的时间复杂度取决于归 (5行)

const flatten = input => {
    result = []
    input.forEach(v => Array.isArray(v) ? result = result.concat(flatten(v)) : result.push(v))
    return result
}

3. 归并方法:reduce

(1行 不过太难于理解了)

reduce的第二个参数:作为归并基础的初始值

const flatten = input => input.reduce((prev, next) => prev.concat(Array.isArray(next) ? flatten(next) : next), []);

4. ...扩展运算符(ES6)

5行代码

const flatten = input => {
    while(input.some(v => Array.isArray(v))){
        input = [].concat(...input)
    }
    return input
}

5. toString法

一行代码

只适用于数组元素全部为数字的情况下

const flatten = ary => ary.toString().split(",").map(v => +v)

数组去重

1. 一般方法

const uniq = input => input.reduce((cur, next) => cur.indexOf(next) !== -1 ? cur : [...cur, next], [])
  • 对象键值 &#javascript是干什么的043; reduce 去重

速度最快, 占空间最多(空间换时间&javascript#xff09;

该方法执行的速度比其他任何方法都快, 就是占用的内存大一些。
现思路:新建一js对象以及新数组,遍历传入数组时,判断值是否为js对象的键,
不是的话给对象新增该键并放入新数组。
注意点:判断是否为js对象键时,会自动对传入的键执行“toString()”,
不同的键可能会被误认为一样,例如n[val]-- n[1]、n["1"];
解决上述问题还是得调用“indexOf”。*/
const obj = {}
const uniq = input => input.reduce((cur, next) => obj[next] ? cur : obj[next] = true && [...cur, next], [])

2. 排序相邻去重

一行搞定排序 + 去重

const uniq = input => input.sort((a, b) => a > b).reduce((cur, next) => cur[cur.length - 1] === next ? cur : [...cur, next], [])

3.数组下标法

const uniq = input => input.reduce((cur, next, i) => input.indexOf(next) !== i ? cur : [...cur, next], [])

4. Set去重

const uniq = input => [... new Set(input)]