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