Skip to content

Instantly share code, notes, and snippets.

@trygvea
Created February 15, 2019 13:51
Show Gist options
  • Save trygvea/3473589f7e504adb07c24cfbd5a7648b to your computer and use it in GitHub Desktop.
Save trygvea/3473589f7e504adb07c24cfbd5a7648b to your computer and use it in GitHub Desktop.
// Objects with only numeric properties that can be treated as a n-dimensional vector
export type Vector<T> = {
[P in keyof T]: number
};
const vextend = <T>(obj: Vector<T>, key: string, val: number): Vector<T> => Object.assign(obj, { [key]: val });
export const vreduce = <T, R>(obj: Vector<T>, reducer: (agg: R, [key, val]: [string, number]) => R, init: R): R =>
Object.entries(obj)
.reduce((agg, [key, val]: [string, number]) => reducer(agg, [key, val]), init);
export const vmap = <T>(v: Vector<T>, mapper: (key: keyof T, val: number) => number): Vector<T> =>
vreduce(v, (agg, [key, val]) => vextend(v, key, mapper(key as keyof T, val)),
{}
) as Vector<T>; // cannot make ts induce that mapping over all keys will transform a {} into the full Vector<T>
export const vmult = <T>(v: Vector<T>, k: number): Vector<T> =>
vmap(v, (key, val) => val * k);
export const vplus = <T>(v1: Vector<T>, v2: Vector<T>): Vector<T> =>
vmap(v1, (key, val) => val + v2[key]);
export const vlength = <T>(v: Vector<T>): number =>
vreduce(v, (agg, [key, val]) => agg + val * val, 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment