前言

在工作时,解决后端传来的一棵树,偶尔发现最初生成的数组存在反复的值。这种时候,当然是要和后端进行交换的。尽管在前端也能够解决,然而如果这棵树也被应用到其余中央,那就须要屡次解决,显然前端对数组进行去重是不合理的。但去重的办法也须要把握,于是有了这篇文章。

数组去重的8种办法

先来个数组,把所有类型都蕴含进来:

const arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}]

一、利用new Set():

这种办法是ES6种最罕用的数组去重办法。
function deduplication(arr) {    return Array.from(new Set(arr))}console.log(deduplication(arr))

二、利用开展运算符“...”:

这种办法不言而喻,就是简化了new Set()。其实应该和new Set()算作同一种办法。
console.log([...new Set(arr)])

三、利用for循环+splice()去重:

太根底了,但根底的货色最重要。关键在于j = i + 1,这一步操作将内外层循环紧密联系起来,就是说如果外层的i为0,则内层的j为从1开始遍历,也就是说,每次循环都会比拟i = 0和j = 从1开始的每一个元素,判断这两个元素是否全等,如果全等则将索引为j的元素从数组移出,也就是说!!!如果第一趟的数组length为12,则第二趟它的length为12或更小。
function deduplication(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)            }        }    }    return arr}

四、利用indexOf():

也很根底,也很重要,重点在于对空数组应用indexOf办法。咱们都晓得如果indexOf的元素如果在数组中不存在,则会返回-1,于是利用这个反思路,如果是-1就将这个值推到一个新的数组中。
function deduplication(arr) {    if (!Array.isArray(arr)) {        throw Error("TypeError: 参数必须为数组类型")    }    let newArr = []    for (let i = 0; i < arr.length; i++) {        if (newArr.indexOf(arr[i]) === -1) {            newArr.push(arr[i])        }    }    return newArr}

五、利用sort():

先对数组进行排序,而后把排序后的第一个元素放到新数组中,这么做是为了避免i - 1 < 0,而后for循环时i的初始值就是1。而后后一个和前一个比拟,如果不全等则推到新数组中。
function deduplication(arr) {    if (!Array.isArray(arr)) {        throw Error("TypeError: 参数必须为数组类型")    }    arr.sort()    let newArr = [arr[0]]    for (let i = 1; i < arr.length; i++) {        if (arr[i] !== arr[i - 1]) {            newArr.push(arr[i])        }    }    return newArr}

六、利用includes():

原理很简略,但须要充沛了解includes这个办法。它返回的是一个boolean类型值,就是说如果这个数组蕴含这个值则为true,否则为false。依照这个逻辑,如果一个新数组中蕴含了这个值则不会往这个数组里push这个元素。反过来说,如果这个值不在新数组中,那么就把这个值push到这个新数组。

function deduplication(arr) {    if (!Array.isArray(arr)) {        throw Error("TypeError: 参数必须为数组类型")    }    let newArr = []    for (let i = 0; i < arr.length; i++) {        if (!newArr.includes(arr[i])) {            newArr.push(arr[i])        }    }    return newArr}

七、利用filter():

对数组进行过滤,return前面的内容是过滤的条件,会返回一个新的数组。这里的条件利用了indexOf(item, 0),这个用法很少用到但并不难理解,item不必多说示意的是要查找的元素,而0则示意start,也就是起始地位,从索引为0开始查找。那么进行过滤的条件就示意,如果这个元素在原数组中首次呈现的地位等于以后项的索引则push到新数组中。
function deduplication(arr) {    return arr.filter((item, index, arr) => {        //console.log(item, index, arr) //以后项、以后项索引、数组自身        //console.log(arr.indexOf(item, 0)) //以后项在原数组首次呈现的地位        return arr.indexOf(item, 0) === index    })}

八、利用reduce():

首先须要对reduce进行一个深刻理解。图中写错了,不是和,是计算结果。例如return prev + next则返回的是和,同样return prev * next则返回的是乘积。

还是举个例子吧:

而后开始利用reduce进行去重,了解了reduce的用法之后就简略很多了。这段代码的关键在于传入初始值“[]”,就是说首先须要让prev变成一个数组,而后在遍历时判断这个数组中是否蕴含了以后值,如果曾经蕴含则prev不变,如果没有则将以后值拼接到prev中。
function deduplication(arr) {    return arr.reduce((prev, next) => {        // console.log(prev, next) //prev初始为[]        // console.log(Array.isArray(prev)) //true        return prev.includes(next) ? prev : prev.concat(next)    }, []) //“[]”为传递给函数的初始值}
tips:数组的concat能够拼接任意对象

总结

数组去重这种操作在前端简直不会用到,除非某些特地状况下。但钻研这些办法可能让咱们对其用法以及原理有更加粗浅的把握和了解。


Keep foolish, keep hungry.