Created
December 3, 2012 23:10
-
-
Save rwaldron/4198955 to your computer and use it in GitHub Desktop.
Comparison of MultiMap with and without @NAMEs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// based on https://mail.mozilla.org/pipermail/es-discuss/2012-December/026799.html | |
import @iterator from '@iter'; | |
class MultiMap { | |
private @keys, @vals; | |
constructor(iterable = []) { | |
this.@keys = []; | |
this.@vals = []; | |
for (let [k, v] of iterable) { | |
this.append(k, v); | |
} | |
} | |
get(key) { | |
const keys = this.@keys; | |
const i = indexOfIdentical(keys, key); | |
return i < 0 ? undefined : this.@vals[i]; | |
} | |
getAll(key) { | |
const keys = this.@keys; | |
const vals = this.@vals; | |
const arr = []; | |
for (var i = 0; i < keys.length; i++) { | |
if (keys[i] is key) { | |
arr.push(vals[i]); | |
} | |
} | |
return arr; | |
} | |
has(key, ...val) { | |
const keys = this.@keys; | |
if (val.length == 0) { | |
return indexOfIdentical(keys, key) >= 0; | |
} else { | |
const vals = this.@vals; | |
for (const [i, k] of keys) { | |
if (k is key && vals[i] is val[0]) { | |
return true; | |
} | |
} | |
return false; | |
} | |
} | |
set(key, ...val) { | |
const keys = this.@keys; | |
const vals = this.@vals; | |
var vali = 0; | |
for (var i = 0; i < keys.length; i++) { | |
if (keys[i] is key) { | |
if (vali < val.length) { | |
vals[i] = val[vali]; | |
vali++; | |
} else { | |
keys.splice(i, 1); | |
vals.splice(i, 1); | |
i--; | |
} | |
} | |
} | |
if (vali < val.length) { | |
this.push(key, ...val.slice(vali)); | |
} | |
return this; | |
} | |
append(key, ...val) { | |
const keys = this.@keys; | |
const vals = this.@vals; | |
val.forEach(e => { | |
keys.push(key); | |
vals.push(val); | |
}); | |
return this; | |
} | |
delete(key, ...val) { | |
const keys = this.@keys; | |
const vals = this.@vals; | |
for (let i = 0; i < keys.length; i++) { | |
if (keys[i] is key && (val.length == 0 || indexOfIdentifical(val, vals[i]) >= 0)) { | |
keys.splice(i, 1); | |
vals.splice(i, 1); | |
i--; | |
} | |
} | |
return this; | |
} | |
*groupedItems() { | |
var seenAlready = new Set(); | |
var keys = this.@keys; | |
for (var i = 0; i < keys.length; i++) { | |
if (seenAlready.has(keys[i])) | |
continue; | |
seenAlready.add(keys[i]); | |
yield [keys[i], this.getAll(keys[i])]; | |
} | |
} | |
*keys() { | |
for (var i = 0; i < [email protected]; i++) { | |
yield this.@keys[i]; | |
} | |
} | |
*values() { | |
for (var i = 0; i < [email protected]; i++) { | |
yield this.@vals[i]; | |
} | |
} | |
*@iterator { | |
for (var i = 0; i < [email protected]; i++) { | |
yield [this.@keys[i], this.@vals[i]]; | |
} | |
} | |
} | |
Object.defineProperty(MultiMap.prototype, 'items', { | |
configurable: true, | |
writable: true, | |
value: MultiMap.prototype.@iterator | |
}); | |
function indexOfIdentical(keys, key) { | |
for (var i = 0; i < keys.length; i++) { | |
if (Object.is(keys[i], key)) { | |
return i; | |
} | |
} | |
return -1; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// based on https://mail.mozilla.org/pipermail/es-discuss/2012-December/026799.html | |
import iterator from '@iter'; | |
import Symbol from '@symbol'; | |
const keysSymbol = new Symbol(); | |
const valsSymbol = new Symbol(); | |
class MultiMap { | |
constructor(iterable = []) { | |
this[keysSymbol] = []; | |
this[valsSymbol] = []; | |
for (let [k, v] of iterable) { | |
this.append(k, v); | |
} | |
} | |
get(key) { | |
const keys = this[keysSymbol]; | |
const i = indexOfIdentical(keys, key); | |
return i < 0 ? undefined : this[valsSymbol][i]; | |
} | |
getAll(key) { | |
const keys = this[keysSymbol]; | |
const vals = this[valsSymbol]; | |
const arr = []; | |
for (var i = 0; i < keys.length; i++) { | |
if (keys[i] is key) { | |
arr.push(vals[i]); | |
} | |
} | |
return arr; | |
} | |
has(key, ...val) { | |
const keys = this[keysSymbol]; | |
if (val.length == 0) { | |
return indexOfIdentical(keys, key) >= 0; | |
} else { | |
const vals = this[valsSymbol]; | |
for (const [i, k] of keys) { | |
if (k is key && vals[i] is val[0]) { | |
return true; | |
} | |
} | |
return false; | |
} | |
} | |
set(key, ...val) { | |
const keys = this[keysSymbol]; | |
const vals = this[valsSymbol]; | |
var vali = 0; | |
for (var i = 0; i < keys.length; i++) { | |
if (keys[i] is key) { | |
if (vali < val.length) { | |
vals[i] = val[vali]; | |
vali++; | |
} else { | |
keys.splice(i, 1); | |
vals.splice(i, 1); | |
i--; | |
} | |
} | |
} | |
if (vali < val.length) { | |
this.push(key, ...val.slice(vali)); | |
} | |
return this; | |
} | |
append(key, ...val) { | |
const keys = this[keysSymbol]; | |
const vals = this[valsSymbol]; | |
val.forEach(e => { | |
keys.push(key); | |
vals.push(val); | |
}); | |
return this; | |
} | |
delete(key, ...val) { | |
const keys = this[keysSymbol]; | |
const vals = this[valsSymbol]; | |
for (let i = 0; i < keys.length; i++) { | |
if (keys[i] is key && (val.length == 0 || indexOfIdentifical(val, vals[i]) >= 0)) { | |
keys.splice(i, 1); | |
vals.splice(i, 1); | |
i--; | |
} | |
} | |
return this; | |
} | |
*items() { | |
for (var i = 0; i < this[keysSymbol].length; i++) { | |
yield [this[keysSymbol][i], this[valsSymbol][i]]; | |
} | |
} | |
*groupedItems() { | |
var seenAlready = new Set(); | |
var keys = this[keysSymbol]; | |
for (var i = 0; i < keys.length; i++) { | |
if (seenAlready.has(keys[i])) | |
continue; | |
seenAlready.add(keys[i]); | |
yield [keys[i], this.getAll(keys[i])]; | |
} | |
} | |
*keys() { | |
for (var i = 0; i < this[keysSymbol].length; i++) { | |
yield this[keysSymbol][i]; | |
} | |
} | |
*values() { | |
for (var i = 0; i < this[keysSymbol].length; i++) { | |
yield this[valsSymbol][i]; | |
} | |
} | |
} | |
Object.defineProperty(MultiMap.prototype, iterator, { | |
configurable: true, | |
writable: true, | |
value: MultiMap.prototype.items | |
}); | |
function indexOfIdentical(keys, key) { | |
for (var i = 0; i < keys.length; i++) { | |
if (Object.is(keys[i], key)) { | |
return i; | |
} | |
} | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment