一、数组去重
let srcArray = [1, 2, 3, 4, 1, 2, 3, 4]
1. 双层循环+splice
注: splice删除了一个元素,下标要减一,否则循环会漏掉一个元素(多个相邻的元素 可能会漏掉删除元素)
for(let i=0;i<srcArray.length - 1;i++){
for(let j = i+1;j<srcArray.length;j++){
if(srcArray[i] === srcArray[j] ){
srcArray.splice(j,1);
j--;
}
}
} // srcArray=[1, 2, 3, 4]
2. new Set(数组)
注:Set是一系列无序、没有重复值的数据集合,传入一个需要去重的数组,Set会自动删除重复的
let tarArray =Array.from(new Set(srcArray ))
// tarArray = [1, 2, 3, 4]
3. sort()排序+比较前后相邻元素是否相同
srcArray.sort()
// 排序之后,第一个元素要么是唯一的,要么是和后面的元素重复
// 把旧数组的第一个元素之间添加到新数组array中
let newarray = [srcArray[0]]
for(let i=1;i<srcArray.length;i++){
if (arr[i] !== arr[i-1]){
newarray.push(arr[i])
}
}
\\ newarray = [1, 2, 3, 4]
4. forEach+indexOf (利用对象属性key排除重复项)
注:遍历数组,每次判断新数组中是否存在该属性,不存在就存储在新数组中
srcArray.forEach((key,index)=>{
if(newArr.indexOf(key) === -1){ newArr.push(key) }
}) //newArr=[1, 2, 3, 4]
这个方法的优点是效率高,缺点是使用了额外空间
5. filter() + indexOf()
let tarArray = srcArray.filter((item, index, array) => {
return array.indexOf(item) === index
}) // tarArray = [1, 2, 3, 4]
6. forEach+includes (includes 方法区分大小写)
let tarArray = []
srcArray.forEach((key,index)=>{
if(!srcArray.includes(key)){
tarArray.push(key)
}}) //tarArr=[1, 2, 3, 4]
7. hasOwnProperty()
hasOwnProperty( ) 方法用于检测一个对象是否含有特定的自身属性,返回一个布尔值
let obj={ }
srcArray.filter(function(item,index,arr){
//typeof item + item是数组的元素item的类型与值拼接在一起,作为obj对象的属性,这个属性是唯一的
return obj.hasOwnProperty(typeof item + item)? false : (obj[typeof item +item] = true)
})
8. reduce() + includes
注:利用reduce()的 “累加器”原理,保存一个唯一项的运行列表。
利用reduce遍历和传入一个空数组作为去重后的新数组,然后内部判断新数组中是否存在当前遍历的元素,不存在就插入新数组
let tarArray = srcArray.reduce((unique, item) => { unique.includes(item) ? unique : [...unique, item] }, [])
// tarArray = [1, 2, 3, 4]
二、对象去重
对象不用去重的!!!对象的属性的一个特点就是元素不能相同, 甚至还可以利用这个特性来去重。
三、对象数组去重
const arr = [{"id":1,"name":"张三"},{"id":2,"name":"李四"},{"id":3,"name":"王五"},{"id":2,"name":"张三"}];
1. 双层循环+splice
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i].id === arr[j].id) {
arr.splice(j, 1);
j - - ;
}
}
} // arr= [{"id":1,"name":"张三"},{"id":2,"name":"李四"},{"id":3,"name":"王五"}]
2. for循环+新数组
let result = [];
for ( let i = 0; i < arr.length; i++) {
var flag = true;
for ( let j = 0; j < result.length; j++) {
if (arr[i].id=== result[j].id) {
flag = false;
}
}
if (flag) {
result.push(arr[i]);
}
} // result = [{"id":1,"name":"张三"},{"id":2,"name":"李四"},{"id":3,"name":"王五"}]
3. 利用对象属性
let result = [];
let obj = {};
for (let i = 0; i < arr.length; i++) {
if (!obj[arr[i].id]) {
result.push(arr[i]);
obj[arr[i].id] = true;
}
} // result = [{"id":1,"name":"张三"},{"id":2,"name":"李四"},{"id":3,"name":"王五"}]
4. for of + find
这个方法的思想与方法2类似 :创建一个空的唯一数组来存储唯一对象;循环遍历数组中的对象。对于每个对象,如果它不是重复的,则将其添加到唯一数组。否则,忽略它。
const unique = [];
for (let item of arr) {
const isDuplicate = unique.find((obj) => obj.id === item.id);
if (!isDuplicate) {
unique.push(item);
}
}
5.filter() + findIndex()
注:filter() 方法过滤掉重复的元素,使用 findIndex() 方法判断对象是否重复
const uniqueArr = arr.filter((item, index) => arr.findIndex(i => i.id === item.id) === index);
// uniqueArr = [{"id":1,"name":"张三"},{"id":2,"name":"李四"},{"id":3,"name":"王五"}]
6. forEach() + some()
注:forEach() 方法遍历数组,使用 some() 方法判断是否重复
const uniqueArr = [];
arr.forEach(item => {
if (!uniqueArr.some(i => i.id === item.id)) {
uniqueArr.push(item);
}
});
7. reduce()
注: reduce第一个参数是遍历需要执行的函数,第二个参数是item的初始值
let obj = {}; //利用对象属性唯一性
newarr = arr.reduce(function(item, next) {
obj[next.id] ? ' ' : obj[next.id] = true && item.push(next);
return item;
}, []);或者
//利用find()
const uniqueArr = arr.reduce((acc, curr) => {
if (!acc.find(item => item.id === curr.id)) {
acc.push(curr);
}
return acc;
}, []);
// newarr = [{"id":1,"name":"张三"},{"id":2,"name":"李四"},{"id":3,"name":"王五"}]
8. Map()
注: has方法可以判断Map对象中是否存在指定元素,有则返回true,否则返回false
set方法可以向Map对象添加新元素 map.set(key, value)
values方法可以返回Map对象值的遍历器对象
let res = new Map();
for (let i of arr) {
if (!res.has(i.id)) {
res.set(i.id, i);
}
}
arr = [...res.values()];// arr = [{"id":1,"name":"张三"},{"id":2,"name":"李四"},{"id":3,"name":"王五"}]
或者
const newarr = [...new Map(arr.map(item => [item.id, item])).values()];
或者 // Array.form()类数组转化为数组
const res = new Map();
let newlist = Array.form(
list.filter((arr) => !res.has(arr.id) && res.set(arr.id, 1) )
)
总结:对象数组的去重,大多是在数组去重的基础上处理的,利用对象或数组的方法或属性,组合运用。掌握了数组的去重,对象数组的去重基本一个套路,也就好弄了。