-
Notifications
You must be signed in to change notification settings - Fork 112
/
09.06.Set1.js
72 lines (65 loc) · 3.24 KB
/
09.06.Set1.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
function Set() { // This is the constructor
this.values = {}; // The properties of this object hold the set
this.n = 0; // How many values are in the set
this.add.apply(this, arguments); // All arguments are values to add
}
// Add each of the arguments to the set.
Set.prototype.add = function() {
for(var i = 0; i < arguments.length; i++) { // For each argument
var val = arguments[i]; // The value to add to the set
var str = Set._v2s(val); // Transform it to a string
if (!this.values.hasOwnProperty(str)) { // If not already in the set
this.values[str] = val; // Map string to value
this.n++; // Increase set size
}
}
return this; // Support chained method calls
};
// Remove each of the arguments from the set.
Set.prototype.remove = function() {
for(var i = 0; i < arguments.length; i++) { // For each argument
var str = Set._v2s(arguments[i]); // Map to a string
if (this.values.hasOwnProperty(str)) { // If it is in the set
delete this.values[str]; // Delete it
this.n--; // Decrease set size
}
}
return this; // For method chaining
};
// Return true if the set contains value; false otherwise.
Set.prototype.contains = function(value) {
return this.values.hasOwnProperty(Set._v2s(value));
};
// Return the size of the set.
Set.prototype.size = function() { return this.n; };
// Call function f on the specified context for each element of the set.
Set.prototype.foreach = function(f, context) {
for(var s in this.values) // For each string in the set
if (this.values.hasOwnProperty(s)) // Ignore inherited properties
f.call(context, this.values[s]); // Call f on the value
};
// This internal function maps any JavaScript value to a unique string.
Set._v2s = function(val) {
switch(val) {
case undefined: return 'u'; // Special primitive
case null: return 'n'; // values get single-letter
case true: return 't'; // codes.
case false: return 'f';
default: switch(typeof val) {
case 'number': return '#' + val; // Numbers get # prefix.
case 'string': return '"' + val; // Strings get " prefix.
default: return '@' + objectId(val); // Objs and funcs get @
}
}
// For any object, return a string. This function will return a different
// string for different objects, and will always return the same string
// if called multiple times for the same object. To do this it creates a
// property on o. In ES5 the property would be nonenumerable and read-only.
function objectId(o) {
var prop = "|**objectid**|"; // Private property name for storing ids
if (!o.hasOwnProperty(prop)) // If the object has no id
o[prop] = Set._v2s.next++; // Assign it the next available
return o[prop]; // Return the id
}
};
Set._v2s.next = 100; // Start assigning object ids at this value.