webai/archive/ioset.ts
2024-08-29 16:09:44 -07:00

64 lines
1.5 KiB
TypeScript

// TODO: remove this, Set is already insertion-ordered in javascript!
/** an insertion ordered set */
export default class IOSet<T> {
// NOTE: this data structure could be improved to have O(1)
// deletion time if `list` is swapped out with a linked
// list instead of an array.
map: Map<T, number>;
list: T[];
constructor(values?: Iterable<T>) {
this.map = new Map();
this.list = [];
if (values !== undefined) this.extend(values);
}
has(v: T) {
return this.map.has(v);
}
add(v: T) {
if (!this.map.has(v)) {
this.map.set(v, this.list.length);
this.list.push(v);
}
}
delete(v: T) {
const idx = this.map.get(v);
if (idx === undefined) return false;
this.map.delete(v);
this.list.splice(idx, 1);
return true;
}
extend(values: Iterable<T>) {
for (const v of values) {
this.add(v);
}
}
shift() {
const v = this.list[0]!;
// NOTE: performance could be boosted since no need for this.map.get(v) and if
this.delete(v);
return v;
}
pop() {
const v = this.list[this.list.length - 1]!;
// NOTE: performance could be boosted since no need for this.map.get(v) and if
this.delete(v);
return v;
}
get size() {
return this.list.length;
}
[Symbol.iterator]() {
return this.list[Symbol.iterator]();
}
}