/** * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal */ export class EquivalenceClassesImpl { private id = 0; private byHash = new Map(); readonly groups: K[][] = []; private createGroup(key: K, value: V) { const id = this.id++; const keys = [key]; this.groups[id] = keys; return { id, keys, value }; } // Return the group representative. add(key: K, a: V) { const hash = this.getHash(a); if (this.byHash.has(hash)) { const groups = this.byHash.get(hash)!; for (let i = 0, _i = groups.length; i < _i; i++) { const group = groups[i]; if (this.areEqual(a, group.value)) { group.keys[group.keys.length] = key; return group.value; } } const group = this.createGroup(key, a); groups[groups.length] = group; return group.value; } else { const group = this.createGroup(key, a); this.byHash.set(hash, [group]); return group.value; } } constructor(private getHash: (v: V) => any, private areEqual: (a: V, b: V) => boolean) { } } export function EquivalenceClasses(getHash: (x: V) => any, areEqual: (a: V, b: V) => boolean) { return new EquivalenceClassesImpl(getHash, areEqual); }