Oops, forgot bag.ts
This commit is contained in:
parent
38584c40bd
commit
afca804797
|
@ -0,0 +1,77 @@
|
|||
// Bags and Deltas (which are Bags where item-counts can be negative).
|
||||
|
||||
import { Value, Set, Dictionary, DefaultPointer } from 'preserves';
|
||||
|
||||
export enum ChangeDescription {
|
||||
PRESENT_TO_ABSENT = -1,
|
||||
ABSENT_TO_ABSENT = 0,
|
||||
ABSENT_TO_PRESENT = 1,
|
||||
PRESENT_TO_PRESENT = 2,
|
||||
}
|
||||
|
||||
export class Bag<T extends object = DefaultPointer> {
|
||||
_items: Dictionary<number, T>;
|
||||
|
||||
constructor(s?: Set<T>) {
|
||||
this._items = new Dictionary();
|
||||
if (s) s.forEach((v) => this._items.set(v, 1));
|
||||
}
|
||||
|
||||
get(key: Value<T>): number {
|
||||
return this._items.get(key, 0) as number;
|
||||
}
|
||||
|
||||
change(key: Value<T>, delta: number, clamp: boolean = false): ChangeDescription {
|
||||
let oldCount = this.get(key);
|
||||
let newCount = oldCount + delta;
|
||||
if (clamp) {
|
||||
newCount = Math.max(0, newCount);
|
||||
}
|
||||
|
||||
if (newCount === 0) {
|
||||
this._items.delete(key);
|
||||
return (oldCount === 0)
|
||||
? ChangeDescription.ABSENT_TO_ABSENT
|
||||
: ChangeDescription.PRESENT_TO_ABSENT;
|
||||
} else {
|
||||
this._items.set(key, newCount);
|
||||
return (oldCount === 0)
|
||||
? ChangeDescription.ABSENT_TO_PRESENT
|
||||
: ChangeDescription.PRESENT_TO_PRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._items = new Dictionary();
|
||||
}
|
||||
|
||||
includes(key: Value<T>): boolean {
|
||||
return this._items.has(key);
|
||||
}
|
||||
|
||||
get size(): number {
|
||||
return this._items.size;
|
||||
}
|
||||
|
||||
keys(): IterableIterator<Value<T>> {
|
||||
return this._items.keys();
|
||||
}
|
||||
|
||||
entries(): IterableIterator<[Value<T>, number]> {
|
||||
return this._items.entries();
|
||||
}
|
||||
|
||||
forEach(f: (count: number, value: Value<T>) => void) {
|
||||
this._items.forEach(f);
|
||||
}
|
||||
|
||||
snapshot(): Dictionary<number, T> {
|
||||
return this._items.clone();
|
||||
}
|
||||
|
||||
clone(): Bag<T> {
|
||||
const b = new Bag<T>();
|
||||
b._items = this._items.clone();
|
||||
return b;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue