Skip to content

Instantly share code, notes, and snippets.

@tschneidereit
Created November 3, 2013 21:15
Show Gist options
  • Save tschneidereit/7294906 to your computer and use it in GitHub Desktop.
Save tschneidereit/7294906 to your computer and use it in GitHub Desktop.
Iterable WeakMap implemented using Weak References
function IterableWeakKeyMap() {
const keyMap = new WeakMap();
const refValueMap = new Map();
return Object.freeze({
get: function(key) {
const entry = keyMap.get(key);
return entry && entry.value;
},
set: function(key, value) {
const ref = makeWeakRef(key);
keyMap.set(key, {value: value, ref: ref});
refValueMap.set(ref, value);
ref.register(function() {
refValueMap.delete(ref);
});
},
delete: function(key) {
const entry = keyMap.get(key);
if (!entry) {
return;
}
keyMap.delete(key);
refValueMap.delete(entry.ref);
},
iterator: function() {
for (const item of refValueMap) {
const key = item[0].get();
if (key) {
yield [key, item[1]];
}
}
},
items: function() {
return this.iterator();
},
keys: function() {
for (const ref of refValueMap.keys()) {
const key = ref.get();
if (key) {
yield key;
}
}
},
values: function() {
// Not sure if we also need to filter these
return refValueMap.values();
}
});
}
@petternordholm
Copy link

A warning if using the code above. There is a bug in the set method if the same key is used multiple times. This will cause multiple weak references for the same key in the #refMap. A simple solution is to call this.delete(ref) after creating the WeakRef .

map = new IterableWeakMap():
const key1 = Symbol('1');

map.set(key1, 'TEST_1');
map.set(key1, 'TEST_1_1');

map.values() // Returns ['TEST_1', 'TEST_1_1']

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment