-
-
Notifications
You must be signed in to change notification settings - Fork 92
/
default-map.js
162 lines (137 loc) · 3.23 KB
/
default-map.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
/**
* Mnemonist DefaultMap
* =====================
*
* JavaScript implementation of a default map that will return a constructed
* value any time one tries to access an inexisting key. It's quite similar
* to python's defaultdict.
*/
/**
* DefaultMap.
*
* @constructor
*/
function DefaultMap(factory) {
if (typeof factory !== 'function')
throw new Error('mnemonist/DefaultMap.constructor: expecting a function.');
this.items = new Map();
this.factory = factory;
this.size = 0;
}
/**
* Method used to clear the structure.
*
* @return {undefined}
*/
DefaultMap.prototype.clear = function() {
// Properties
this.items.clear();
this.size = 0;
};
/**
* Method used to get the value set for given key. If the key does not exist,
* the value will be created using the provided factory.
*
* @param {any} key - Target key.
* @return {any}
*/
DefaultMap.prototype.get = function(key) {
var value = this.items.get(key);
if (typeof value === 'undefined') {
value = this.factory(key, this.size);
this.items.set(key, value);
this.size++;
}
return value;
};
/**
* Method used to get the value set for given key. If the key does not exist,
* a value won't be created.
*
* @param {any} key - Target key.
* @return {any}
*/
DefaultMap.prototype.peek = function(key) {
return this.items.get(key);
};
/**
* Method used to set a value for given key.
*
* @param {any} key - Target key.
* @param {any} value - Value.
* @return {DefaultMap}
*/
DefaultMap.prototype.set = function(key, value) {
this.items.set(key, value);
this.size = this.items.size;
return this;
};
/**
* Method used to test the existence of a key in the map.
*
* @param {any} key - Target key.
* @return {boolean}
*/
DefaultMap.prototype.has = function(key) {
return this.items.has(key);
};
/**
* Method used to delete target key.
*
* @param {any} key - Target key.
* @return {boolean}
*/
DefaultMap.prototype.delete = function(key) {
var deleted = this.items.delete(key);
this.size = this.items.size;
return deleted;
};
/**
* Method used to iterate over each of the key/value pairs.
*
* @param {function} callback - Function to call for each item.
* @param {object} scope - Optional scope.
* @return {undefined}
*/
DefaultMap.prototype.forEach = function(callback, scope) {
scope = arguments.length > 1 ? scope : this;
this.items.forEach(callback, scope);
};
/**
* Iterators.
*/
DefaultMap.prototype.entries = function() {
return this.items.entries();
};
DefaultMap.prototype.keys = function() {
return this.items.keys();
};
DefaultMap.prototype.values = function() {
return this.items.values();
};
/**
* Attaching the #.entries method to Symbol.iterator if possible.
*/
if (typeof Symbol !== 'undefined')
DefaultMap.prototype[Symbol.iterator] = DefaultMap.prototype.entries;
/**
* Convenience known methods.
*/
DefaultMap.prototype.inspect = function() {
return this.items;
};
if (typeof Symbol !== 'undefined')
DefaultMap.prototype[Symbol.for('nodejs.util.inspect.custom')] = DefaultMap.prototype.inspect;
/**
* Typical factories.
*/
DefaultMap.autoIncrement = function() {
var i = 0;
return function() {
return i++;
};
};
/**
* Exporting.
*/
module.exports = DefaultMap;