-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
177 lines (170 loc) · 6 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
'use strict';
/**
* Returns `Set` class with custom equality comparisons.
*
* @param {function} hashFn — the function to determine the unique of value.
* @returns {HashSet}
*/
module.exports = function hashSet(hashFn) {
if (!hashFn) {
throw new Error('You should specify hash function to create HashSet.');
}
/**
* Set objects are collections of values, you can iterate its elements in insertion order.
*
* A value in the Set may only occur once; it is unique in the Set's collection.
*/
return class HashSet {
/**
* The value of the length property is 0.
*/
static get length() {
return 0;
}
/**
* Returns the function that created an instance's prototype.
*
* @param {Iterable} iterable — if an iterable object is passed, then all of its elements
* will be added to the new Set. `null` is treated as undefined.
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of}
*/
constructor(iterable) {
this._map = new Map();
if (iterable) {
for (let item of iterable) {
this.add(item);
}
}
}
/**
* The value of size is an integer representing how many entries the Set object has.
* A set accessor function for size is undefined; you can not change this property.
*
* @returns {number} the number of elements in a Set object.
*/
get size() {
return this._map.size;
}
/**
* Appends a new element with the given value to the Set object.
*
* @param {*} value — the value of the element to add to the Set object.
* @returns {HashSet}.
*/
add(value) {
const id = hashFn(value);
if (!this._map.has(id)) {
this._map.set(id, value);
}
return this;
}
/**
* Returns a boolean asserting whether an element is present with the given value in the Set object or not.
*
* @param {*} value — the value to test for presence in the Set object.
* @returns {boolean} Returns true if an element with the specified value exists in the Set object;
* otherwise false.
*/
has(value) {
const id = hashFn(value);
return this._map.has(id);
}
/**
* Removes the element associated to the value and returns the value that.
*
* `Set.prototype.has(value)` would have previously returned.
* `Set.prototype.has(value)` will return false afterwards.
*
* @param {*} value — the value of the element to remove from the Set object.
* @returns {boolean} Returns true if an element in the Set object has been removed successfully;
* otherwise false.
*/
delete(value) {
const id = hashFn(value);
return this._map.delete(id);
}
/**
* Removes all elements from the Set object.
*/
clear() {
this._map.clear();
}
/**
* Returns a new Iterator object that contains an array of [value, value] for each element in the Set object,
* in insertion order.
*
* This is kept similar to the Map object, so that each entry has the same value for its key and value here.
*
* @returns {Iterator}
*/
entries() {
return this._map.values();
}
/**
* Executes a provided function once per each value in the Set object, in insertion order.
*
* It is not invoked for values which have been deleted. However, it is executed for values which are present
* but have the value undefined.
*
* Callback is invoked with three arguments:
* * the element value
* * the element key
* * the Set object being traversed
*
* @param {function} callbackFn — function to execute for each element.
* @param {object} thisArg — value to use as this when executing callback. If a thisArg parameter is provided
* to forEach, it will be used as the this value for each callback.
*/
forEach(callbackFn, thisArg) {
this._map.forEach((value, key) => callbackFn.call(thisArg, value, key, this));
}
/**
* Returns a new Iterator object that contains the values for each element in the Set object in insertion order.
*
* Is the same function as the values() function.
*
* @returns {Iterator}
*/
values() {
return this._map.values();
}
/**
* Returns a new Iterator object that contains the values for each element in the Set object in insertion order.
*
* Is the same function as the values() function.
*
* @returns {Iterator}
*/
keys() {
return this._map.values();
}
/**
* The initial value of the @@iterator property is the same function object as the initial
* value of the values property.
*
* Is the same function as the values() function.
*
* @returns {Iterator}
*/
[Symbol.iterator]() {
return this._map.values();
}
/**
* Returns Set object is equivalent to this HashSet object.
*
* @returns {Set}
*/
valueOf() {
return new Set(this._map.values());
}
/**
* Returns a string representing object.
*
* @returns {string}
*/
// eslint-disable-next-line class-methods-use-this
toString() {
return '[object Set]';
}
};
}