本文已参与「新人创作礼」活动,一起开启掘金创作之路。
数组及数组对象去重
1、使用Map数据结构将数组去重
注解:ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键,通过get获取值。先看一个小例子
const myMap = new Map();
const obj = { p: '666'}
myMap.set(0, {id:0, name: '张三'}) // 键值对--键:0, 值:{id:0, name: '张三'}
myMap.set(1, {id:1, name: '李四'}) // 键值对--键:1, 值:{id:1, name: '李四'}
myMap.set(obj, {id:2, name: '王五'}) // 键值对--键:obj,值:{id:2, name: '王五'} 各种类型的值(包括对象)都可以当作键
myMap.get(0) // {"id": 0,"name": "张三"}
myMap.get(1) // {"id": 1,"name": "李四"}
myMap.get(obj) // {"id": 1,"name": "王五"}
console.log([...myMap.values()]) // values()该方法是获取Map中所有的值,并将值通过[...]放在数组中
// [{"id": 0,"name": "张三"},{"id": 1,"name": "李四"},{"id": 2,"name": "王五"}]
小知识:Map有has、delete等方法,上面的例子中,myMap.has(1) 返回true,has中的1是键
请阅读下面的小例子:将下列数组中id相同的项剔除
// 基础数据
const arr1 = [
{id: 1, name: '张三'},
{id: 1, name: '张三'},
{id: 2, name: '李四'},
{id: 2, name: '李四'},
{id: 3, name: '王五'},
{id: 4, name: '孟六'},
]
// 去重方法
const map = new Map() // 新建一个Map数据
for (const item of arr1) { // 循环基础数据,获得基础数据的每一项item
if (!map.has(item.id)) { // 判断map中是否含有基础数据项中以item中的id命名的键,如果没有
map.set(item.id, item) // 就将基础数据中的item的id为键,item为值,set到map数据结构中
}
}
// 最终结果
const arr2 = [...map.values()]
console.log(arr2)
// [
// {"id": 1,"name": "张三"},
// {"id": 2,"name": "李四"},
// {"id": 3,"name": "王五"},
// {"id": 4,"name": "孟六"}
// ]
2、使用reduce去重(将下列数组中id相同的项剔除)
注解:方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
const arr1 = [
{id: 1,name: '小明'},
{id: 1,name: '小明'},
{id: 2,name: '小丽'},
{id: 2,name: '小丽'},
{id: 3,name: '李四'},
{id: 4,name: '王五'},
{id: 1,name: '小明'},
]
const obj = {};
const arr2 = arr1.reduce((total, item) => {
obj[item.id] ? "" : (obj[item.id] = true && total.push(item));
return total;
}, []);
console.log(arr2)
// [
// {"id": 1,"name": "小明"},
// {"id": 2,"name": "小丽"},
// {"id": 3,"name": "李四"},
// {"id": 4,"name": "王五"}
// ]
3、使用Array.from()和new Set()去重
// set具有唯一性,所以会自动去重
const a = [1,2,3]
const b = [2,3,4]
const c = [1,2,3,4,5,6,7,8,9,7,8,9]
const res = Array.from(new Set([...a, ...b, ...c]))
console.log(res) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
注意:对于数组对象并不适用,只会合并,不回去重,请阅读下面的例子
const a = [{name: '张三', age: 18},{name:'李四', age: 19}]
const b = [{name: '王五'}]
const c = [{name: '王五'},{name: '张三', age: 18}]
const d = [{name: '王五'}]
const res = Array.from(new Set([...a, ...b,...c, ...d]))
console.log(res)
// [{name: '张三', age: 18},
// {name: '李四', age: 19},
// {name: '王五'},
// {name: '王五'},
// {name: '张三', age: 18},
// {name: '王五'}]
// new Set还可以用于字符串去重
const a = [...new Set('123123456')].join()
console.log(a) // '1,2,3,4,5,6'
4、使用filter数组去重
注解:创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,不会改变原数组
const arr1 = [1,2,3,4]
const arr2 = [3,4,5,6,7,8,9]
const arr3 = arr1.concat(arr2.filter(v => !arr1.includes(v)))
console.log(arr3) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
注意:该方法对于数组对象并不适用,只会合并不会去重,请阅读下面的例子
// 单独的filter无法满足合并去重
const arr1 = [{name: '王五'}]
const arr2 = [{name: '王五'},{name: '张三', age: 18}]
const arr3 = arr1.concat(arr2.filter(v => !arr1.includes(v)))
console.log(arr3)
// [{"name": "王五"},{"name": "王五"},{"name": "张三","age": 18}]
filter配合使用every来去重,例如将下列数组合并,剔除id相同的项
const arr1 = [{id: 1,name: '张三'},{id: 2,name:'李四'}]
const arr2 = [{id: 1,name: '王五'},{id: 3,name:'张三'}]
const arr3 = arr2.concat(arr1.filter(x =>
arr2.every(y => y.id != x.id)
))
console.log(arr3) //[{"id": 1,"name": "王五"},{ "id": 3, "name": "张三"},{"id": 2,"name": "李四"}]