JS不可重复集合MySet(扩展Set,集合元素支持对象去重)

Set介绍

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。添加使用add()方法,长度为size属性,判断包含元素用has()方法,遍历可使用for of 或者 forEach()方法。

Set添加对象

但是Set集合的元素,如果添加多个对象,则除非是同一个对象,才可以去重。如果添加多个对象,但是对象中的属性和值都相同,由于Set是采用 === 比较对象的,所以多个相同属性和值的对象,是可以添加进去的。

扩展Set,支持对象去重

由于笔者项目中,有遇到需要对对象集合进行去重的需要,所以自定义了MySet,继承自Set,重写了add、has方法,使其支持添加对象时,自动去重。
原理:利用一个对象,key来记录已经添加的对象计算出的唯一值,来确保添加对象时,重复的唯一值的对象不再添加。

MySet实现

MySet继承自Set,主要是重写了add()方法、has()、delete()方法,可以传入一个方法,用来计算添加或比较的对象的唯一值,该值作为对象的唯一标记。

/**
 * 自定义Set,支持添加对象去重(指定对象值方法)
 */
class MySet extends Set {
	constructor(params, valFnc) {
		super();
		this.valObject = {};
		
		if (params) {
			// 构造函数传入集合,调用add方法初始化
			for (let item of params) {
				this.add(item, valFnc);
			}
		}
	}
	add(val, valFnc) {
		if (valFnc) {
			// 该对象计算出的值存在,则返回,不添加
			if (this.valObject[valFnc(val)]) {
				return;
			}
			// 标记存在
			this.valObject[valFnc(val)] = true;
		}
		super.add(val);
	}
	has(val, valFnc) {
		if (valFnc) {
			return this.valObject[valFnc(val)] ? true : false;
		}
		return super.has(val);
	}
	delete(val, valFnc) {
		if (valFnc) {
			let del = null;
			for (let item of this) {
				if (valFnc(val) === valFnc(item)) {
					this.valObject[valFnc(val)] = false;
					del = item;
					break;
				}
			}
			return super.delete(del);;
		} else {
			return super.delete(val);
		}
	}
	clear() {
		this.valObject = {};
		super.clear();
	}
}

MySet使用

由于继承了Set对象,所以完全可以像使用Set一样来使用MySet

let mySet = new MySet();
// MySet元素值获取方法
let valFnc = (v) => v.name;

mySet.add({name: "张三"}, valFnc);
mySet.add({name: "李四"}, valFnc);
mySet.add({name: "张三"}, valFnc);
mySet.add({name: "王五"}, valFnc);

console.log(mySet.size); // 3
console.log(mySet.has({name: "张三"}, valFnc)); // true

console.log(mySet.delete({name: "张三"}, valFnc)) // true
console.log(mySet.size); // 3
console.log(mySet);

let array = [{
	name: "a"
}, {
	name: "b"
}, {
	name: "c"
}, {
	name: "b"
}];

let s1 = new MySet(array);
console.log(s1.size); // 4

let s2 = new MySet(array, valFnc);
console.log(s2.size); // 3
console.log(s2.has({name: "a"}, valFnc)); // true
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JavaScript中,可以使用Set对象来实现数组和对象的重操作。Set是一种新的数据结构,类似于数组,但是可以去除重复的值。但需要注意的是,对于存储引用类型的值,Set无法自动去重,因为相同的引用值在内存中的地址是不一样的。只有当引用值的地址完全相同才会被认为是重复的。下面是一个例子: ```javascript var mySet = new Set(); mySet.add([-1, 0, 1]); mySet.add([-1, 0, 1]); mySet.add({a: 1}); mySet.add({a: 1}); console.log(Array.from(mySet)); ``` 输出结果为:[[-1, 0, 1], [-1, 0, 1], {a: 1}, {a: 1}],可以看到,数组和对象重复值并没有被自动去重。 如果想要对多维数组和对象进行深层的去重操作,常见的方法是使用Set结合filter函数进行操作。但是需要注意的是,Set和filter只能对一维数组进行去重,无法进行深层的去重。如果需要对多维数组和对象进行深层的去重,可以使用递归的方法判断是否为对象,如果是对象则继续递归判断其值是否为数组或对象,以此类推。 总结来说,通过使用Set对象可以实现对数组和对象去重操作,但对于存储引用类型的值需要注意地址的唯一性。如果需要对多维数组和对象进行深层的去重操作,可以结合递归和判断值的类型来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [new set数组对象去重失败](https://blog.csdn.net/qq_22182989/article/details/129386809)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [多维数组和对象-深去重和深拷贝.js](https://download.csdn.net/download/weixin_44786867/12702478)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值