一、遍历数组法
思路1:新建一个新数组res
,遍历原数组,每次判断原数组值不在新数组中,就push
到新数组。
function unique (arr) {
let res = [];
for (let i = 0; i < arr.length; i++) {
if (res.indexOf(arr[i]) === -1) { //indexOf 等于 -1 时代表数组中没有该值
res.push(arr[i]);
}
}
return res;
}
let oldArr = [1,3,5,4,3,6,5];
let newArr = unique(oldArr);
思路2:新建一个数组res
,如果新数组中该值i
不存在,则向原数组添加push(i)
。
for…of 循环的 i 代表的是 value(多用于数组),for…in 循环的是 key(多用于对象)。
function unique (arr) {
let res = [];
for (let i of arr) {
!res.includes(i) && res.push(i);
}
return res;
}
let oldArr = [1,3,5,4,3,6,5];
let newArr = unique(oldArr);
二、哈希表思想
新建一个数组res
、一个存储标志的对象hash
,遍历数组,对象中arr[i]
对应的值为true
的时候不重复添加。
function unique (arr) {
let res = [], hash = {};
// 遍历前四个数时,hash 表中没有这四个值,所以 if 语句成立,将数据 push 到 res 中,令这些表中的数都为 true。
// 当遍历到第二个 3 的时候,之前已经令 hash[i] = true,所以 if 语句就不执行了,就不会重复了
for (let i of arr) {
if (!hash[i]) {
res.push(i);
hash[i] = true; //是否在数组中存在的标志
}
}
return res;
}
let oldArr = [1,3,5,4,3,6,5];
let newArr = unique(oldArr);
三、数组下标判断法
先遍历,然后判断原数组第 i 项arr[i]
在数组中第一次出现的位置是否与 i 相等,不等说明重复。
function unique (arr) {
let res = [];
for (let i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) === i) {
res.push(arr[i]);
}
}
return res;
}
四、排序,去除相邻重复值
对数组排序后,先把 0 号元素放入新数组,将新数组的最后一个值与原数组的当前值进行比较,相等说明重复。
function unique (arr) {
arr.sort();
let res = [arr[0]];
for (let i = 1; i < arr.length; i++) {
if (arr[i] != res[res.length - 1]) {
res.push(arr[i]);
}
}
return res;
}
五、双层循环遍历
思路1:有重复值时终止当前循环i
,进入外层循环i+1
,找到的是往后遍历不会有重复值的值。
function unique (arr) {
let res = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i+1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
++i;
}
}
res.push(arr[i]);
}
return res;
}
思路2:两层循环遍历,如果有重复的值,则用splice()
删除
function unique (arr) {
let len = arr.length;
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1); // splice 会改变原数组长度,所以要将数组长度 len 和下标 j 减一
len--;
j--;
}
}
}
return arr;
}
六、ES6 的 Set 去重
Set 类型
:ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的。Set 函数可以将数组作为参数。
Set
创建的对象有四个方法:add
、delete
、has
、clear
。
function unique (arr) {
let res = new Set(arr);
return [...res];
// 上面的两行代码可以简写成:
// return Array.from(new Set(arr))
}
七、ES6 的 Array.filter() 过滤
筛选条件:数组下标与检索下标一致。
filter()
方法不会改变原数组,而是返回一个新数组。
function unique (arr) {
return arr.filter((item, index) => {
return arr.indexOf(item) === index
})
}