Skip to content

Commit b943746

Browse files
committed
Native maps & sets.
This is a bit awkward because Node doesn’t enable Harmony collections by default, and even with --harmony, Map and Set don’t support forEach. Also, this commit doesn’t preserve a fallback for when Map and Set aren’t available, and still has to wrap the Map and Set objects for backwards-compatibility. Blech.
1 parent 1fc660a commit b943746

4 files changed

Lines changed: 113 additions & 111 deletions

File tree

d3.js

Lines changed: 55 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -241,64 +241,53 @@
241241
}); else for (var key in object) map.set(key, object[key]);
242242
return map;
243243
};
244-
function d3_Map() {}
244+
function d3_Map() {
245+
this._ = new Map();
246+
}
245247
d3_class(d3_Map, {
246-
has: d3_map_has,
248+
has: function(key) {
249+
return this._.has(key + "");
250+
},
247251
get: function(key) {
248-
return this[d3_map_prefix + key];
252+
return this._.get(key + "");
249253
},
250254
set: function(key, value) {
251-
return this[d3_map_prefix + key] = value;
255+
return this._.set(key + "", value);
256+
},
257+
remove: function(key) {
258+
return this._.delete(key + "");
259+
},
260+
keys: function() {
261+
var i = this._.keys(), k, keys = [];
262+
while (!(k = i.next()).done) keys.push(k.value);
263+
return keys;
252264
},
253-
remove: d3_map_remove,
254-
keys: d3_map_keys,
255265
values: function() {
256-
var values = [];
257-
this.forEach(function(key, value) {
258-
values.push(value);
259-
});
266+
var i = this._.values(), v, values = [];
267+
while (!(v = i.next()).done) values.push(v.value);
260268
return values;
261269
},
262270
entries: function() {
263-
var entries = [];
264-
this.forEach(function(key, value) {
265-
entries.push({
266-
key: key,
267-
value: value
268-
});
271+
var i = this._.entries(), e, entries = [];
272+
while (!(e = i.next()).done) entries.push({
273+
key: e[0],
274+
value: e[1]
269275
});
270276
return entries;
271277
},
272-
size: d3_map_size,
273-
empty: d3_map_empty,
278+
size: function() {
279+
return this._.size;
280+
},
281+
empty: function() {
282+
return !!this._.size;
283+
},
274284
forEach: function(f) {
275-
for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) f.call(this, key.slice(1), this[key]);
285+
var that = this;
286+
this._.forEach(function(key, value) {
287+
f.call(that, key, value);
288+
});
276289
}
277290
});
278-
var d3_map_prefix = "\x00", d3_map_prefixCode = d3_map_prefix.charCodeAt(0);
279-
function d3_map_has(key) {
280-
return d3_map_prefix + key in this;
281-
}
282-
function d3_map_remove(key) {
283-
key = d3_map_prefix + key;
284-
return key in this && delete this[key];
285-
}
286-
function d3_map_keys() {
287-
var keys = [];
288-
this.forEach(function(key) {
289-
keys.push(key);
290-
});
291-
return keys;
292-
}
293-
function d3_map_size() {
294-
var size = 0;
295-
for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) ++size;
296-
return size;
297-
}
298-
function d3_map_empty() {
299-
for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) return false;
300-
return true;
301-
}
302291
d3.nest = function() {
303292
var nest = {}, keys = [], sortKeys = [], sortValues, rollup;
304293
function map(mapType, array, depth) {
@@ -367,22 +356,35 @@
367356
if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);
368357
return set;
369358
};
370-
function d3_Set() {}
359+
function d3_Set() {
360+
this._ = new Set();
361+
}
371362
d3_class(d3_Set, {
372-
has: d3_map_has,
363+
has: function(value) {
364+
return this._.has(value + "");
365+
},
373366
add: function(value) {
374-
this[d3_map_prefix + value] = true;
375-
return value;
367+
return this._.add(value + "");
376368
},
377369
remove: function(value) {
378-
value = d3_map_prefix + value;
379-
return value in this && delete this[value];
370+
return this._.delete(value + "");
371+
},
372+
values: function() {
373+
var i = this._.values(), v, values = [];
374+
while (!(v = i.next()).done) values.push(v.value);
375+
return values;
376+
},
377+
size: function() {
378+
return this._.size;
379+
},
380+
empty: function() {
381+
return !!this._.size;
380382
},
381-
values: d3_map_keys,
382-
size: d3_map_size,
383-
empty: d3_map_empty,
384383
forEach: function(f) {
385-
for (var value in this) if (value.charCodeAt(0) === d3_map_prefixCode) f.call(this, value.slice(1));
384+
var that = this;
385+
this._.forEach(function(value) {
386+
f.call(that, value);
387+
});
386388
}
387389
});
388390
d3.behavior = {};

d3.min.js

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/arrays/map.js

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,60 +7,48 @@ d3.map = function(object) {
77
return map;
88
};
99

10-
function d3_Map() {}
10+
function d3_Map() {
11+
this._ = new Map;
12+
}
1113

1214
d3_class(d3_Map, {
13-
has: d3_map_has,
15+
has: function(key) {
16+
return this._.has(key + "");
17+
},
1418
get: function(key) {
15-
return this[d3_map_prefix + key];
19+
return this._.get(key + "");
1620
},
1721
set: function(key, value) {
18-
return this[d3_map_prefix + key] = value;
22+
return this._.set(key + "", value);
23+
},
24+
remove: function(key) {
25+
return this._.delete(key + "");
26+
},
27+
keys: function() {
28+
var i = this._.keys(), k, keys = [];
29+
while (!(k = i.next()).done) keys.push(k.value);
30+
return keys;
1931
},
20-
remove: d3_map_remove,
21-
keys: d3_map_keys,
2232
values: function() {
23-
var values = [];
24-
this.forEach(function(key, value) { values.push(value); });
33+
var i = this._.values(), v, values = [];
34+
while (!(v = i.next()).done) values.push(v.value);
2535
return values;
2636
},
2737
entries: function() {
28-
var entries = [];
29-
this.forEach(function(key, value) { entries.push({key: key, value: value}); });
38+
var i = this._.entries(), e, entries = [];
39+
while (!(e = i.next()).done) entries.push({key: e[0], value: e[1]});
3040
return entries;
3141
},
32-
size: d3_map_size,
33-
empty: d3_map_empty,
42+
size: function() {
43+
return this._.size;
44+
},
45+
empty: function() {
46+
return !!this._.size;
47+
},
3448
forEach: function(f) {
35-
for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) f.call(this, key.slice(1), this[key]);
49+
var that = this;
50+
this._.forEach(function(key, value) {
51+
f.call(that, key, value);
52+
});
3653
}
3754
});
38-
39-
var d3_map_prefix = "\0", // prevent collision with built-ins
40-
d3_map_prefixCode = d3_map_prefix.charCodeAt(0);
41-
42-
function d3_map_has(key) {
43-
return d3_map_prefix + key in this;
44-
}
45-
46-
function d3_map_remove(key) {
47-
key = d3_map_prefix + key;
48-
return key in this && delete this[key];
49-
}
50-
51-
function d3_map_keys() {
52-
var keys = [];
53-
this.forEach(function(key) { keys.push(key); });
54-
return keys;
55-
}
56-
57-
function d3_map_size() {
58-
var size = 0;
59-
for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) ++size;
60-
return size;
61-
}
62-
63-
function d3_map_empty() {
64-
for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) return false;
65-
return true;
66-
}

src/arrays/set.js

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,40 @@
11
import "../core/class";
2-
import "map";
32

43
d3.set = function(array) {
54
var set = new d3_Set;
65
if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);
76
return set;
87
};
98

10-
function d3_Set() {}
9+
function d3_Set() {
10+
this._ = new Set;
11+
}
1112

1213
d3_class(d3_Set, {
13-
has: d3_map_has,
14+
has: function(value) {
15+
return this._.has(value + "");
16+
},
1417
add: function(value) {
15-
this[d3_map_prefix + value] = true;
16-
return value;
18+
return this._.add(value + "");
1719
},
1820
remove: function(value) {
19-
value = d3_map_prefix + value;
20-
return value in this && delete this[value];
21+
return this._.delete(value + "");
22+
},
23+
values: function() {
24+
var i = this._.values(), v, values = [];
25+
while (!(v = i.next()).done) values.push(v.value);
26+
return values;
27+
},
28+
size: function() {
29+
return this._.size;
30+
},
31+
empty: function() {
32+
return !!this._.size;
2133
},
22-
values: d3_map_keys,
23-
size: d3_map_size,
24-
empty: d3_map_empty,
2534
forEach: function(f) {
26-
for (var value in this) if (value.charCodeAt(0) === d3_map_prefixCode) f.call(this, value.slice(1));
35+
var that = this;
36+
this._.forEach(function(value) {
37+
f.call(that, value);
38+
});
2739
}
2840
});

0 commit comments

Comments
 (0)