import { chooseRandom } from "./utils.ts"; export default class Collection extends Map { maxSize?: number; set(key: K, value: V) { // When this collection is maxSizeed make sure we can add first if (this.maxSize || this.maxSize === 0) { if (this.size >= this.maxSize) return this; } return super.set(key, value); } array() { return [...this.values()]; } first() { return this.values().next().value; } last() { return [...this.values()][this.size - 1]; } random() { return chooseRandom([...this.values()]); } find(callback: (value: V, key: K) => boolean) { for (const key of this.keys()) { const value = this.get(key)!; if (callback(value, key)) return value; } // If nothing matched return; } filter(callback: (value: V, key: K) => boolean) { const relevant = new Collection(); this.forEach((value, key) => { if (callback(value, key)) relevant.set(key, value); }); return relevant; } map(callback: (value: V, key: K) => T) { const results = []; for (const key of this.keys()) { const value = this.get(key)!; results.push(callback(value, key)); } return results; } some(callback: (value: V, key: K) => boolean) { for (const key of this.keys()) { const value = this.get(key)!; if (callback(value, key)) return true; } return false; } every(callback: (value: V, key: K) => boolean) { for (const key of this.keys()) { const value = this.get(key)!; if (!callback(value, key)) return false; } return true; } reduce( callback: (accumulator: T, value: V, key: K) => T, initialValue?: T, ): T { let accumulator: T = initialValue!; for (const key of this.keys()) { const value = this.get(key)!; accumulator = callback(accumulator, value, key); } return accumulator; } }