Created
December 11, 2024 05:49
-
-
Save asleepace/eb2df968c7c3ab3f8de709f1b51c6782 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Key / Value container which enforces a max capacity and | |
* provides several methods for iteration. | |
* | |
* Demo: | |
* https://www.typescriptlang.org/play/?target=99#code/PQKhCgAIUyGkCmBPSxIDUCGAbArgyAYwHsA7AF0wEtSEAnSAdwAsrDnIFSAzYuwhAGdImSAFtMADyKYADpkJVyKTKQAmUGJFl1iANypqhkQQj30c4hOWbE1w3gyUXyVMgDpIm4OELZMgsIAgnR0mEgAsnIAPAAqALyqSAB8kADe4FCw2nRUepjkBBKSAMJyCkpIAFyQpLhiAEb0kPGQACxZsDp5BQQ0pnTkAPJ0RnQ1guS5pADmANoAui2Qi505PYUm5HwINQBKCCSj0ZPTMwA0kLGprWkAvpnZ2rgN2GyQM9ZExLgUABQAShqdUazQyTyedGsuDopEgQwaACtDuR3ABrZCCP42KiCdyTHYA9zYLgzGxrB5rUAQCEwADKXxsBAxSGA+TwBHkVAYqjUTCo2GwnAMhHIkGI2DGnAouSEa2gkCo3HEUhk8kUykVwihCmYCDUngAksrVMK2K4yOLCIQYcJ5TAccJGAKhThBMRIFDyDC4UyzaL9ZB2fh3PafE9ZC83oQTNY-iyJlMaBcgzh8DVYkCrpAAD5B4iGdLy7KO9z9ejDUb0dy-QSsbjkePIAHF2ClglQuYspatYMIVtMVgkyDY1h4ki-MWpUvFMrqyoAosQ5ffUiTTiSWTc-WIFCtUvlwYjMbuWTEWSAgdPJUjhCb7dqXeQABkz43W6hj+Qit9Y-x2yhRdwRXECSDXMU7w-fUsA5ZZ2wAhA5kgh9dwWK8VyMElNngnYkPvT9UPQ5cvR9d8Hxg-AiMgB4QJo7JKQjKN3k+RsEy2M4s1iXNIF+IxuBoQNgOI6FYUgHDO27ClHmySNXneKExH0BAm2qdjkyzBpiAlBBTSEiEsMgNRDAORTzGWbg3X7ECDzXCtj2afc-0PSsT347BCjoP4-g7HdmxaVI9JAm8VJaeJWh8r8kCAqinkw6wCHExDJJAkCjLUEylLguhKJSlcSNEqYcty6jOGwUwl2KyERLhCyyqs4q6OXO4WxA-K4TSjLzCktZZOjERBUBDNFgq4TvQKpzbKPKs6HcCQLxUxd4mnP8fK7ZAFha+jpK6JiYz8HTPKzPQCz5QKSxWhDlnuAcbIGFyHJWNCngYmTdpVC9CBwbAGgUNEaj+GhI3IDNFtSTMhqWM7YDasSJru+yZrmryWVBkaUrA9dnDEOCLtw5LioxsVaEkMVWk+wUfsINEAcKMRNtyxK1qQHtajvcgqJh4n2do+nqO2545JjNyPL+cnvt+-61AKTAQf8yBNO01ROOGqHYdxMtJvuhhHPV5yEfcYX6GRvylrR0CyHXPscfV1b8dywmtQAMQFDzAzJr7KepvteZAqjgtxZ33PofVF1LBSlIW-nWuqp2XeDjQeakylgDQABRSRMDEWRh1wQRME+TIHc+9gCFaWhGEgEIwkiGIQSaOhkkvYu9XxOMACIpcoABGNvLi7gAmABmFtm4QVvGw76X+979ou4AVhH3Ux9MCfO8wQeZ4ANgAdgADkXkvx7+SfKDaGeAE4u4ABgPluV+Pte55nruX5Hi3tOJYgZlFpf3C+wFb5j32pgQ6vh34kk-t-Uef8BoAkAUfE+mBN7PyHi2Xwv8kY0wQHTOWWMFT9zQRjD+2Av4-0Pv-OBQA | |
* | |
*/ | |
class ArrayMap<T=any> { | |
private maxCapacity: number = 4 | |
private insertOrder: string[] = [] | |
private store: Record<string, T> = {} | |
public get count(): number { | |
return Object.keys(this.store).length | |
} | |
/** | |
* Set the key/value pair and will evict older entries | |
* if max capacity is reached. If an eviction occurs | |
* this will also return the evicted value. | |
*/ | |
public set(key: string, value: T): T | void { | |
this.insertOrder.unshift(key) | |
this.store[key] = value | |
while (this.count > this.maxCapacity) { | |
const expiredKey = this.insertOrder.pop() | |
if (expiredKey && expiredKey in this.store) { | |
const expiredValue = this.store[expiredKey] | |
delete this.store[expiredKey] | |
return expiredValue | |
} | |
} | |
} | |
public get(key: string): T | undefined { | |
return this.store[key] | |
} | |
public remove(key: string): boolean { | |
let didRemove = false | |
this.insertOrder = this.insertOrder.filter((storedKey) => { | |
if (key === storedKey) { | |
delete this.store[key] | |
didRemove = true | |
return true | |
} else { | |
return false | |
} | |
}) | |
return didRemove | |
} | |
public all(): T[] { | |
return this.insertOrder.map((key) => this.store[key]) | |
} | |
public clear(): void { | |
this.store = {} | |
this.insertOrder = [] | |
} | |
public map(callback: (input: T) => T): T[] { | |
return this.insertOrder.map((key) => { | |
const item = this.store[key] | |
const next = callback(item) | |
this.store[key] = next | |
return next | |
}) | |
} | |
public filter(callback: (data: T) => boolean): T[] { | |
this.insertOrder = this.insertOrder.filter((key) => { | |
const value = this.store[key] | |
const isFiltered = callback(value) | |
if (isFiltered) this.remove(key) | |
return isFiltered | |
}) | |
} | |
} | |
// Example usage | |
const cache = new ArrayMap<number>() | |
cache.set("data1", 123) | |
cache.set("data2", 415) | |
cache.set("data3", 678) | |
cache.set("data4", 910) | |
cache.set("data5", 111) | |
console.log(cache.all()) | |
cache.clear() | |
console.log(cache.all()) | |
cache.set("data6", 123) | |
cache.map((item) => item * 2) | |
console.log(cache.all()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment