79 lines
1.7 KiB
TypeScript
79 lines
1.7 KiB
TypeScript
interface SetPolyfillInterface<T> {
|
|
add(value: T): void
|
|
delete(value: T): boolean
|
|
has(value: T): boolean
|
|
clear(): void
|
|
forEach(
|
|
callback: (value: T, value2: T, set: SetPolyfill<T>) => void,
|
|
thisArg?: any
|
|
): void
|
|
readonly size: number
|
|
}
|
|
|
|
class SetPolyfill<T> implements SetPolyfillInterface<T> {
|
|
private items: Record<string, T>
|
|
|
|
constructor(initialValues?: T[]) {
|
|
this.items = {}
|
|
if (initialValues) {
|
|
for (const value of initialValues) {
|
|
this.add(value)
|
|
}
|
|
}
|
|
}
|
|
|
|
add(value: T): void {
|
|
const key = JSON.stringify(value)
|
|
this.items[key] = value
|
|
}
|
|
|
|
delete(value: T): boolean {
|
|
const key = JSON.stringify(value)
|
|
if (this.has(value)) {
|
|
delete this.items[key]
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
has(value: T): boolean {
|
|
const key = JSON.stringify(value)
|
|
return Object.prototype.hasOwnProperty.call(this.items, key)
|
|
}
|
|
|
|
clear(): void {
|
|
this.items = {}
|
|
}
|
|
|
|
forEach(
|
|
callback: (value: T, value2: T, set: SetPolyfill<T>) => void,
|
|
thisArg?: any
|
|
): void {
|
|
for (const key in this.items) {
|
|
if (Object.prototype.hasOwnProperty.call(this.items, key)) {
|
|
callback.call(thisArg, this.items[key], this.items[key], this)
|
|
}
|
|
}
|
|
}
|
|
|
|
get size(): number {
|
|
return Object.keys(this.items).length
|
|
}
|
|
|
|
[Symbol.iterator](): Iterator<T> {
|
|
let index = 0
|
|
const values = Object.values(this.items)
|
|
return {
|
|
next: (): IteratorResult<T> => {
|
|
if (index < values.length) {
|
|
return { value: values[index++], done: false }
|
|
} else {
|
|
return { value: undefined, done: true }
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
export default SetPolyfill
|