数组去重的常用方法
1.indexOf
-
利用数组的key属性,遍历对象,查找数组中是否存在这个属性,不存在则返回新数组中
-
优点是效率高,缺点是使用了额外空间
// 普通数组 const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]; let newArr = []; arr.forEach(item=>{ if(newArr.indexOf(item)<0){ newArr.push(item) } }) console.log(newArr);// [1, '1', 17, true, false, 'true', 'a', {}, {}] // 对象数组 let arrObj = [ { name: "小红", id: 1 }, { name: "小橙", id: 1 }, { name: "小黄", id: 4 }, { name: "小绿", id: 3 }, { name: "小青", id: 1 }, { name: "小蓝", id: 4 } ]; function fn2(tempArr) { let newArr = []; for (let i = 0; i < tempArr.length; i++) { if (newArr.indexOf(tempArr[i].id) == -1) { newArr.push(tempArr[i].id); } else { tempArr.splice(i, 1); i--; }; }; return tempArr; }; console.log(fn2(arrObj)); // [ { name: '小红', id: 1 }, { name: '小黄', id: 4 }, { name: '小绿', id: 3 } ]
2.new Set()
- Set是一系列无序、没有重复值的数据集合,传入一个需要去重的数组,Set会自动删除重复的元素,再将Set转数组返回
- 效率高,代码清晰,缺点是存在兼容性问题
// 普通数组
const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}];
const newArr = [...new Set(arr)];
console.log(newArr);// [1, '1', 17, true, false, 'true', 'a', {}, {}]
3.new Map()
- 利用Map的键值对同名覆盖,再将Map转数组
// 普通数组
const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}];
const m = new Map();
for (let i = 0; i < arr.length; i++) {
m.set(arr[i], arr[i]);
}
const newArr = []
m.forEach(function (value, key) {
newArr .push(value)
})
console.log(newArr );//[1, '1', 17, true, false, 'true', 'a', {}, {}]
// 对象数组
let arrObj = [
{ name: "小红", id: 1 },
{ name: "小橙", id: 1 },
{ name: "小黄", id: 4 },
{ name: "小绿", id: 3 },
{ name: "小青", id: 1 },
{ name: "小蓝", id: 4 }
];
// 方法一:
let map = new Map();
for (let item of arrObj) {
if (!map.has(item.id)) {
map.set(item.id, item);
};
};
arr = [...map.values()];
console.log(arr);
// [ { name: '小红', id: 1 }, { name: '小黄', id: 4 }, { name: '小绿', id: 3 } ]
// 方法二: (代码较为简洁)
const map = new Map();
const newArr = arrObj.filter(v => !map.has(v.id) && map.set(v.id, 1));
console.log(newArr);
// [ { name: '小红', id: 1 }, { name: '小黄', id: 4 }, { name: '小绿', id: 3 } ]
4.filter() + indexof
- filter把接收的函数依次作用于每一个数组项,然后根据返回值 true or false 决定是否保留该值
- 优点在于可在去重时插入对元素的操作,可拓展性强
// 普通数组
const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}];
const newArr= arr.filter(function(item,index,self){
return self.indexOf(item) === index;
})
console.log(newArr);// [1, '1', 17, true, false, 'true', 'a', {}, {}]
5.reduce() + includes
- reduce()把结果继续和序列的下一个元素做累加计算
- 利用reduce遍历和传入一个空数组作为去重后的新数组,然后内部判断新数组中是否存在当前遍历的元素,不存在就插入新数组
- 缺点在于时间消耗多,内存空间也额外占用
// 普通数组
const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}];
const newArray = arr.reduce((newArr, element) => {
if (!newArr.includes(element)) {
newArr.push(element);
}
return newArr;
}, []);
6.双层for循环
// 普通数组
// 对象数组
let arrObj = [
{ name: "小红", id: 1 },
{ name: "小橙", id: 1 },
{ name: "小黄", id: 4 },
{ name: "小绿", id: 3 },
{ name: "小青", id: 1 },
{ name: "小蓝", id: 4 }
];
function fn1(tempArr) {
for (let i = 0; i < tempArr.length; i++) {
for (let j = i + 1; j < tempArr.length; j++) {
if (tempArr[i].id == tempArr[j].id) {
tempArr.splice(j, 1);
j--;
};
};
};
return tempArr;
};
console.log(fn1(arrObj));
// [ { name: '小红', id: 1 }, { name: '小黄', id: 4 }, { name: '小绿', id: 3 } ]
7.reduce 对象数组去重
let arr = [
{
key:'1',
name:'林青霞'
},
{
key:'2',
name:'张三丰'
},
{
key:'1',
name:'段誉'
},
{
key:'3',
name:'林青霞'
},
]
// 封装方法:根据提供的属性去重
function arrDistinctByProp(arr,prop){
let obj = {};
return arr.reduce(function(preValue,item){
obj[item[prop]] ? '' : obj[item[prop]] = true && preValue.push(item);
return preValue
},[])
}
// 根据name去重
let newArr = arrDistinctByProp(arr,'name')
// 打印返回的新数组
console.log(newArr)
[{
key:'1',
name:'林青霞'
},
{
key:'2',
name:'张三丰'
},
{
key:'1',
name:'段誉'
}]
8.filter 对象数组去重
let arr = [
{
key:'1',
name:'林青霞'
},
{
key:'2',
name:'张三丰'
},
{
key:'1',
name:'段誉'
},
]
let res = arr.filter(function(item,index,self){
return self.findIndex(el=>el.key==item.key)===index
})
console.log(res) // [ { key: '1', name: '林青霞' }, { key: '2', name: '张三丰' } ]
let arr = [
{
key:'1',
name:'林青霞'
},
{
key:'2',
name:'张三丰'
},
{
key:'1',
name:'段誉'
},
{
key:'1',
name:'段誉'
}
]
function arrDistinctByProp(arr,prop){
return arr.filter(function(item,index,self){
return self.findIndex(el=>el[prop]==item[prop])===index
})
}
//通过name属性去重
let res = arrDistinctByProp(arr,'name')
console.log(res);
[
{ key: '1', name: '林青霞' },
{ key: '2', name: '张三丰' },
{ key: '1', name: '段誉' }
]
9. 对象访问属性的方法
let arrObj = [
{ name: "小红", id: 1 },
{ name: "小橙", id: 1 },
{ name: "小黄", id: 4 },
{ name: "小绿", id: 3 },
{ name: "小青", id: 1 },
{ name: "小蓝", id: 4 }
];
function fn3(tempArr) {
let result = [];
let obj = {};
for (let i = 0; i < tempArr.length; i++) {
if (!obj[tempArr[i].id]) {
result.push(tempArr[i]);
obj[tempArr[i].id] = true;
};
};
return result;
};
console.log(fn3(arrObj));
// [ { name: '小红', id: 1 }, { name: '小黄', id: 4 }, { name: '小绿', id: 3 } ]