圧倒的手抜き記事 @ぶぅちゃんズ Advent Calendar
いつも使っているutils.ts
に書いてあったやつをコピペして終わり。
何がしたいか
- JavascriptのSetはプリミティブ型でしか重複なし集合として扱われない
- JavaのHashSetは自分で同値条件を設定できる。同値判定を最小限に抑えるために、hash関数を設定することもできる。
- Javaのやつのほうが便利なことが多いので、HashSet実装する
注意
- Javaは
Java.lang.Object
でメソッドequals
とhashCode
を実装する必要がありますが、同値判定とハッシュ関数は高階関数で実現します。
コーーーーード
export class ObjectSet<T> {
map: Map<string, T[]>
constructor(list: T[], public isEq: (t1: T, t2: T) => boolean, public hash: (t: T) => string) {
this.map = new Map();
for(let l of list) {
this.add(l);
}
}
add(t: T) {
let lst = this.map.get(this.hash(t));
if(lst) {
if(lst.every(l => !this.isEq(l, t))) {
lst.push(t);
}
} else {
this.map.set(this.hash(t), [t]);
}
}
has(t: T): boolean {
let lst = this.map.get(this.hash(t));
return !!lst && lst.some(l => this.isEq(l, t));
}
toList(): T[] {
return Array.from(this.map.entries(), ([_, ts]) => ts).flat();
}
}
12/10 修正:Array.from(m).map(([_, ts]) => ts)
はArray.from(m, ([_, ts]) => ts)
の方が短いし速いので。