Skip to content

Instantly share code, notes, and snippets.

@loucadufault
Last active October 29, 2022 21:08
Show Gist options
  • Save loucadufault/8fcd38a6b409e7fddc2e556027468fbd to your computer and use it in GitHub Desktop.
Save loucadufault/8fcd38a6b409e7fddc2e556027468fbd to your computer and use it in GitHub Desktop.
Collection of various utils for operating on JavaScript / TypeScript objects and arrays in ES6 with strong typing
function countItemFrequency<T extends string | number | symbol>(l: T[]): Record<T, number> {
const occurrences = {} as Record<T, number>;
l.forEach(i => {
if (!occurrences.hasOwnProperty(i)) {
occurrences[i] = 0;
}
occurrences[i]!++;
});
return occurrences;
}
function countByPredicate<T>(l: T[], predicate: (i: T) => boolean): number {
let count = 0;
l.forEach(i => {
if (predicate(i)) {
count++;
}
});
return count;
}
function uniqueByPredicate<T>(l: T[], predicate: (a: T, b: T) => boolean): T[] {
return l.filter((v1, i, a) => a.findIndex(v2 => predicate(v1, v2)) === i);
}
function getKeyOfLargestValue<T extends string | number | symbol>(o: any): T {
return (Object.keys(o) as T[]).reduce((a, b) => o[a] > o[b] ? a : b);
}
function transformKeys<T>(o: Record<string, T>, transform: (k: string, v: T) => string): Record<string, T> {
return Object.fromEntries(
Object.entries(o).map(([k, v]) => [transform(k, v), v])
);
}
/**
* Constructs a new object from the result of applying the transform function to each key-value pair in the given object, where the transform function must return a value of the same type as the object values
*/
function transformValues<T>(o: Record<string, T>, transform: (k: string, v: T) => T): Record<string, T> {
return Object.fromEntries(
Object.entries(o).map(([k, v]) => [k, transform(k, v)])
);
}
/**
* Constructs a new object from the result of applying the transform function to each key-value pair in the given object, where the transform function may return a value of any type
*/
function transformValuesAndTheirType<T>(o: Record<string, T>, transform: (k: string, v: T) => T | any): Record<string, T | any> {
return Object.fromEntries(
Object.entries(o).map(([k, v]) => [k, transform(k, v)])
);
}
function filterByPredicate<T>(o: Record<string, T>, predicate: (k: string, v: T) => boolean): Record<string, T> {
return Object.fromEntries(
Object.entries(o).filter(([k, v]) => predicate(k, v))
);
}
function sortByComparator<T>(o: Record<string, T>, comparator: (entryA: [string, T], entryB: [string, T]) => number): Record<string, T> {
return Object.fromEntries(
Object.entries(o).sort((a,b) => comparator(a, b))
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment