前言
数组去重,可以说是一个比较常见的面试题,今天,小编又刷到了一道关于数组去重的题目,今天那咱们就来盘点一下都有哪些方法可以实现数组去重。
方法一、双重for循环
这是一个最笨重的方法,双重循环。
var arr = [1,2,3,4,5,6,4,3,8,1]
// 数组去重:
// 方法1: 双重for 循环
function newArrFn (arr) {
// 创建一个新的空数组
let newArr = []
for(var i = 0;i<arr.length;i++){
for(var j = i+1;j<arr.length;j++){
if(arr[j]===arr[i]){
break
}
}
if(j==arr.length){
newArr.push(arr[i])
}
};
return newArr
}
console.log(newArrFn(arr));
方法二:for循环+indexof
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法2: for + indexof
function newArrFn (arr) {
let newArr = []
for(let i = 0;i<arr.length;i++){
newArr.indexOf(arr[i]) === -1 ? newArr.push(arr[i]) : newArr
};
return newArr
}
console.log(newArrFn(arr));
在函数体内部,首先创建了一个空数组newArr,用于存放不重复的元素。然后,使用for循环遍历原始数组arr中的每个元素。对于每个元素arr[i],它会检查这个元素是否已经在newArr中存在(通过indexOf方法)。如果newArr.indexOf(arr[i])返回-1,这意味着元素arr[i]在newArr中不存在,因此使用三元运算符将其添加到newArr中。否则,如果元素已经存在,什么也不做。
方法三:sort排序
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法3: for + sort
function newArrFn (arr) {
arr = arr.sort()
let newArr = []
for(let i = 0;i<arr.length;i++){
arr[i] === arr[i-1] ? newArr : newArr.push(arr[i])
};
return newArr
}
console.log(newArrFn(arr));
在这里咱们创建一个新的空数组newArr用于存储不重复的元素。然后使用for循环遍历排序后的数组arr。在每次迭代中,它检查当前元素arr[i]是否与前一个元素arr[i-1]相等。如果它们相等(意味着arr[i]是一个重复项),则不执行任何操作。如果它们不相等,则将当前元素arr[i]推送到newArr中。
方法四:双指针法
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
var newArrFn = function(nums) {
const n=nums.length;
nums=nums.sort((a,b)=>a-b)
if(n==0){
return 0
}
let fast=1,slow=1;
let newArr=[]
newArr.push(nums[fast-1])
while(fast<n){
if(nums[fast]!==nums[fast-1]){
newArr.push(nums[fast])
nums[slow]=nums[fast]
slow++
}
fast++
}
return newArr
};
console.log(newArrFn(arr));
首先对得到的数组进行一个升序排序,接着初始化两个指针fast和slow,都设置为1(即数组的第二个元素的索引)。同时,创建一个空数组newArr,用于存储去重后的元素。这里将nums的第一个元素推入newArr中,因为fast和slow都从1开始,使用while循环遍历数组。在每次迭代中,if语句检查fast指针所指向的元素是否与前一个元素不同。如果是不同的,newArr将添加该元素,并将该元素复制到nums的slow指针所指向的位置,然后slow指针向前移动一位。无论元素是否相同,fast指针都会向前移动一位。最终返回一个新数组newArr即为去重后的数组。
方法五:set
ES6中新增了数据类型Set,Set的一个最大的特点就是数据不重复。Set函数可以接受一个数组(或类数组对象)作为参数来初始化,利用该特性也能做到给数组去重。
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法5: set
function newArrFn (arr) {
// .new Set方法,返回是一个类数组,需要结合 ...运算符,转成真实数组
return ([...new Set(arr)])
}
console.log(newArrFn(arr));
方法六:set + Array.from
利用 set数据不重复的特点,结合 Array.from
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法6: set + Array.from
function newArrFn (arr) {
// .new Set方法,返回是一个类数组,需要结合 Array.from ,转成真实数组
return (Array.from(new Set(arr)) )
}
console.log(newArrFn(arr));
方法七:filter + indexOf
indexOf,可以检测某一个元素在数组中出现的位置,找到返回该元素的下标,没找到返回 -1
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法7 :filter + findIndex
function newArrFn (arr) {
// 利用indexOf检测元素在数组中第一次出现的位置是否和元素现在的位置相等,
// 如果相等,说明数组中没有重复的
return Array.prototype.filter.call(arr, function (item, index) {
return arr.indexOf(item) === index
})
}
console.log(newArrFn(arr));
方法八:includes
利用 includes 检查新数组是否包含原数组的每一项。 如果不包含,就push进去
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法8 :for + includes
function newArrFn (arr) {
// 利用includes 检查新数组是否包含原数组的每一项
// 如果不包含,就push进去
let newArr = []
for(let i = 0;i<arr.length;i++){
newArr.includes(arr[i]) ? newArr: newArr.push(arr[i])
};
return newArr
}
console.log(newArrFn(arr));
方法九:for + object
利用对象属性名不能重复这一特点。如果对象中不存在,就可以给 push 进去
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法9 :for + obj
function newArrFn (arr) {
// 利用对象属性名不能重复这一特点
// 如果对象中不存在,就可以给 push 进去
let newArr = []
let obj = {}
for(let i = 0;i<arr.length;i++){
if (!obj[arr[i]]) {
newArr.push(arr[i])
obj[arr[i]] = 1
} else {
obj[arr[i]] ++
}
};
return newArr
}
console.log(newArrFn(arr));
方法十:for+splice
利用 splice 进行切割
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法10 :for + splice
// 利用 splice 进行切割。
function newArrFn (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
}
console.log(newArrFn(arr));
方法十一:filter + indexOf
利用 filter 过滤 配合 indexOf 查找元素
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法11 :filter + indexOf
// filter 过滤 配合 indexOf 查找元素
function newArrFn (arr) {
return arr.filter((item, index) => {
return arr.indexOf(item) === index
})
}
console.log(newArrFn(arr));
方法十二:Map
利用数据结构存值的特点
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法12 :Map
function newArrFn (arr) {
let newArr = []
let map = new Map()
for(let i = 0;i<arr.length;i++){
// 如果 map里面不包含,就设置进去
if (!map.has(arr[i])) {
map.set(arr[i], true)
newArr.push(arr[i])
}
};
return newArr
}
console.log(newArrFn(arr));
方法十三:reduce
var arr = [1, 2, 3,4 ,5,6, 4, 3, 8, 1]
// 数组去重:
// 方法13 :reduce
function newArrFn (arr) {
let newArr = []
return arr.reduce((prev, next,index, arr) => {
// 如果包含,就返回原数据,不包含,就把新数据追加进去
return newArr.includes(next) ? newArr : newArr.push(next)
}, 0)
}
console.log(newArrFn(arr));
reduce函数是用来对数组的每一个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。在这里,reduce函数的调用形式如下:
(prev, next, index, arr):prev是上一次调用callback返回的值,或者是提供的初始值(在这里是0)。next是当前元素,index是当前元素的索引,arr是原数组。return newArr.includes(next) ? newArr : newArr.push(next):这一行的意图是在newArr不包含next时将next添加到newArr中。但是,这里的问题在于reduce的返回值被忽略了,它不会更新newArr。此外,newArr.push(next)直接返回的是newArr的长度,而不是newArr本身。
好啦,今天的分享就到这里了,不知道屏幕前的你是否还有其他关于数组去重的方法,欢迎评论区留言讨论。可以点个免费的赞赞嘛,感谢感谢!