From 2716b04477bde05a154057d92368ee86f96eaabd Mon Sep 17 00:00:00 2001 From: Andrej Dyck <43913051+andrej-dyck@users.noreply.github.com> Date: Sat, 30 Dec 2023 16:11:35 +0100 Subject: [PATCH] add memoize function --- memoize/index.ts | 14 ++++++++++++++ memoize/memoize.test.ts | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 memoize/index.ts create mode 100644 memoize/memoize.test.ts diff --git a/memoize/index.ts b/memoize/index.ts new file mode 100644 index 0000000..e9cfb16 --- /dev/null +++ b/memoize/index.ts @@ -0,0 +1,14 @@ +/** + * Returns a function that will memoize the return values for arguments of (pure) function f and return those on subsequent calls. + * Note that it only supports functions with exactly 1 argument and the values must be equatable (e.g., objects won't work) + */ +export const memoize = (f: (arg: T) => R): (arg: T) => R => { + const values = new Map() + return (arg: T) => { + if(!values.has(arg)) { + values.set(arg, f(arg)) + } + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return values.get(arg)! + } +} diff --git a/memoize/memoize.test.ts b/memoize/memoize.test.ts new file mode 100644 index 0000000..f9d6816 --- /dev/null +++ b/memoize/memoize.test.ts @@ -0,0 +1,38 @@ +import { describe, expect, test } from 'vitest' +import { memoize } from './index.js' + +describe('memoize', () => { + + test('delegates to function of first call', () => { + const mf = memoize((n: number) => n * 2) + expect(mf(2)).toEqual(4) + }) + + test('uses memoized return value on subsequent calls', () => { + let calls = 0 + const mf = memoize((n: number) => { + calls++ + return n * 2 + }) + + expect(mf(2)).toEqual(4) + expect(mf(2)).toEqual(4) + expect(calls).toEqual(1) + }) + + test('memorizes return value pre argument', () => { + let calls = 0 + const mf = memoize((n: number) => { + calls++ + return n * 2 + }) + + expect(mf(2)).toEqual(4) + expect(mf(2)).toEqual(4) + + expect(mf(1)).toEqual(2) + expect(mf(1)).toEqual(2) + + expect(calls).toEqual(2) + }) +})