Set.js--创建无重复值的无序集合
Set 集合,不同于 Array,是一种没有重复值的集合。
以下代码出自于《JavaScript 权威指南(第六版)》P217,注意:这里并不是指 es6 / es2015 中的 Set 集合。它只是提供了一种实现类的例子,因为代码写得很巧妙,我就想记录下来并分享给大家。
// 定义一个 Set 构造函数
function Set() {
this.values = {}; // values 以键值对的形式表示集合的数据
this.n = 0; // n 集合中值的个数
// arguments 是实际参数的一个类数组对象
// 保证在 new Set(1,'sarah',{}) 初始化构造函数时调用原型上的 add 方法,将传入的参数添加到集合中
this.add.apply(this, arguments);
} // 将每个参数添加至集合中
Set.prototype.add = function() {
// 遍历每一个参数
for (var i = 0; i < arguments.length; i++) {
var val = arguments[i], // 值
str = Set._v2s(val); // 键:通过值得到相应的键
// 保证集合无重复值
if (!this.values.hasOwnProperty(str)) {
this.values[str] = val;
this.n++; // 集合中值的计数加一
}
}
return this; // 支持链式调用
} // 删除元素
Set.prototype.remove = function() {
// 遍历每一个参数
for (var i = 0; i < arguments.length; i++) {
var str = Set._v2s(arguments[i]); // 通过值得到相应的键
if (this.values.hasOwnProperty(str)) { // 若 values 集合中存在该属性
delete this.values[str]; // 删除元素
this.n--; // 集合中值的计数减一
}
}
return this; // 支持链式调用
} // 检测是否包含某个值
Set.prototype.contains = function(value) {
return this.values.hasOwnProperty(Set._v2s(value));
} // 返回集合的大小
Set.prototype.size = function() {
return this.n;
} // 遍历集合中的所有元素,在指定的上下文中调用回调函数 f
Set.prototype.foreach = function(f, context) {
for (var s in this.values) {
if (this.values.hasOwnProperty(s)) {
f.call(context, this.values[s]);
}
}
} // 在 Set 方法上定义一个自定义属性 _v2s
// 该属性的值是一个方法,用于将传入的值转成对应的字符串(其实就像是打标签)
Set._v2s = function(val) {
switch (val) {
case undefined: return 'u'; // 如果是 undefined,就返回 'u'
case null: return 'n';
case true: return 't';
case false: return 'f';
default: switch (typeof val) {
case 'number': return '#' + val; // 如果是数字,就添加 # 前缀 ,例如 #123, #0.5
case 'string': return '"' + val; // 如果是字符串,就添加 " 前缀 , 例如 "hello, "world
default: return '@' + objectId(val); // 如果是数组、函数、对象等,就添加 @ 前缀,objectId 方法会返回一个特定数字,如:@100
}
} function objectId(o) {
var prop = "|**objectid**|"; // 给数组/ 函数/ 对象定义一个私有属性,用以存放 id
if (!o.hasOwnProperty(prop)) { // 添加该属性前先判断该对象是否已经存在该属性
o[prop] = Set._v2s.next++; // 不存在则添加该属性,值为 next
}
return o[prop];
}
}
// 在 Set._v2s.next 方法上定义一个自定义属性 next,初始值为 100
// 这样做的好处是,避免了全局变量污染,并且将该属性与对应的方法绑定在一起
Set._v2s.next = 100;
以上代码就定义好了一个 Set 类,它可以向集合中添加元素,也可以删除元素,还可以查询某个元素是否在该集合中等等。下面我们就来测试一下:
var arr = [3, 4, 5];
var set = new Set(1, 1, 3, 'sarah', null, undefined, function () {}, arr, {});
console.log(set);
打印 set,结果如下:
我在 new Set ( ) 的时候传入了 9 个参数,但打印结果中显示 n = 8,并且参数 1 只出现了一次,即 #1 。这说明了,set 集合不会添加重复值。
其它示例:
var arr = [3, 4, 5];
var set = new Set(1, 1, 3, 'sarah', null, undefined, function () {}, arr, {}); console.log(set.remove(null)); // n = 7
console.log(set.contains('sarah')); // true
console.log(set.contains('lissy')); // false set.add([3, 4, 5]); // 可以成功,因为数组是引用类型,当前添加的这个 [3, 4, 5] 跟之前的 arr 不是指向同一个引用
console.log(set.size()); //
我写这篇文章的目的不在于向大家提供 Set 这个构造函数,主要还是为了加深对类的理解。这其中在函数上定义自定义属性这一操作,是我在之前的代码中没有用到过的,它可以解决一些全局变量的问题,又可以和对应的函数紧密关联在一起,我觉得非常有用。
作者不才,文中若有错误,望请指正,避免误人子弟。
Set.js--创建无重复值的无序集合的更多相关文章
- MYSQL中防止插入重复记录的解决方案(无重复值更新)
说明:一般我们使用MYSQL插入记录时,类似于这样的语句: insert into table_name(email,phone,user_id) values(‘test9@163.com’,’99 ...
- JS 数组去重复值
var arr1 = [90, 91, 92]; var arr2 = [80, 81]; var arr3 = [80, 71, 72, 73]; var arr = arr1.concat(50, ...
- js 数组排除重复值(string)
前提:数组中的元素类型为:string 在网上看了许多高大尚的文章,还是解决不了我的string arry 的问题,只能怪自己脑残了,上代码: <!DOCTYPE html> <ht ...
- js 创建List<Map> 这种格式的集合
//赋值 var list_map = new Array(); for ( var i = 0; i < 10; i++) { list_map.push({baidux:'baidux'+i ...
- js中var的有或无--重复声明和以后的声明
js中var的有或无--重复声明和以后的声明 使用var语句多次声明一个变量不仅是合法的,而且也不会造成任何错误. 如果重复使用的一个声明有一个初始值,那么它担当的不过是一个赋值语句的角色. 如果重复 ...
- JS去除数组中重复值的四种方法
JS去除数组中重复值的四种方法 1 /// <summary> o[this[i]] = ""; } } newArr.p ...
- JS前端无侵入实现防止重复提交请求技术
JS前端无侵入实现防止重复提交请求技术 最近在代码发布测试的过程中,我发现有些请求非常的消耗服务器资源,而系统测试人员因为响应太慢而不停的点击请求.我是很看不惯系统存在不顺眼的问题,做事喜欢精益求精, ...
- 【转】javascript中值传递,地址传递,引用传递的问题(使用js创建list对象时会用到)
function initEditModal_SI(node) { if (node.siArray == undefined) { node.siArray = new Object(); } va ...
- JS两个数组比较,删除重复值巧妙方法
//方法一 var arr1 = [1,2,3,4,5,6,7,8]; //数组A var arr2 = [1,2,3,11,12,13,14];//数组B var temp = []; //临时数组 ...
随机推荐
- [三] java虚拟机 JVM字节码 指令集 bytecode 操作码 指令分类用法 助记符
说明,本文的目的在于从宏观逻辑上介绍清楚绝大多数的字节码指令的含义以及分类 只要认真阅读本文必然能够对字节码指令集有所了解 如果需要了解清楚每一个指令的具体详尽用法,请参阅虚拟机规范 指令简介 计算机 ...
- Python机器学习笔记 异常点检测算法——Isolation Forest
Isolation,意为孤立/隔离,是名词,其动词为isolate,forest是森林,合起来就是“孤立森林”了,也有叫“独异森林”,好像并没有统一的中文叫法.可能大家都习惯用其英文的名字isolat ...
- Using rqt_console and roslaunch
Description: This tutorial introduces ROS using rqt_console and rqt_logger_level for debugging and r ...
- 一统江湖的大前端(3) DOClever——你的postman有点low
<一统江湖的大前端>系列是自己的前端学习笔记,旨在介绍javascript在非网页开发领域的应用案例和发现各类好玩的js库,不定期更新.如果你对前端的理解还是写写页面绑绑事件,那你真的是有 ...
- 第60章 设备流交互服务 - Identity Server 4 中文文档(v1.0.0)
该IDeviceFlowInteractionService接口旨在提供用户界面用于在设备流授权期间与IdentityServer通信的服务.它可以从依赖注入系统获得,通常作为构造函数参数注入到Ide ...
- DSAPI HTTP监听服务端与客户端_指令版
前面介绍了DSAPI多功能组件编程应用-HTTP监听服务端与客户端的内容,这里介绍一个适用于更高效更快速的基于HTTP监听的服务端.客户端. 在本篇,你将见到前所未有的超简化超傻瓜式的HTTP监听服务 ...
- WPF 窗口大小自适应
在设置桌面不同分辨率以及较大DPI下,窗口如何显示的问题. 方案一 设置窗口最大值和最小值显示 通过对比当前屏幕的可显示区域,将窗口高宽最大值和最小值,设置为窗口的实际高宽(此例中仅设置高度) 界面设 ...
- python学习笔记(十 一)、GUI图形用户界面
python图形用户界面就是包含按钮.输入框.选择框等组件的窗口.主要依赖与工具包进行代码编写.python GUI工具包并发互斥的,你可以选择多个工具包进行安装,有极大选择空间.每个工具包都有不同用 ...
- Java学习笔记之——集合
集合是类,用来存储多个数据,有属性.方法 集合是一个可变数组,保存相同元素并且长度可变 1. 体系 (1)Collection:存储一个一个的值 Iterable: Iterable<T> ...
- 聊聊我的 Java 自学之路
最近经常在知乎收到类似『没基础,java 如何自学』.『怎么才能掌握编程』等等问题,再加上发现高中同学也在自学.有感而发,讲讲我的自学之路. 1.1. 大学 高考没正常发挥,考入一所二流的学校,当时分 ...