Skip to content

Instantly share code, notes, and snippets.

@olegchursin
Created July 26, 2022 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olegchursin/c3c905c3117ef235ffd0f823aa6cb9b1 to your computer and use it in GitHub Desktop.
Save olegchursin/c3c905c3117ef235ffd0f823aa6cb9b1 to your computer and use it in GitHub Desktop.
Object utils
type ScoreObj = { [key: string]: number };
// Since we are sure that "scoreObj" is always of type {[key: string]: number;}
// we can use our own typing for Object.entries().
// It is still using a type assertion ("as any") which is not ideal,
// but gives us the right typings in subsequnt methods
type Entries<T> = { [K in keyof T]: [K, T[K]] }[keyof T];
function objectEntries<T extends object>(t: T): Entries<T>[] {
return Object.entries(t) as any;
}
function objectify(arr: [string, unknown][]): any {
return Object.fromEntries(arr);
}
export function getFirstN(obj: ScoreObj, n: number) {
const sliced = objectEntries<ScoreObj>(obj).slice(0, n);
return objectify(sliced);
}
export function getLastN(obj: ScoreObj, n: number) {
const sliced = objectEntries<ScoreObj>(obj).slice(-n);
return objectify(sliced);
}
// provided a sorted array, returns a new array
// sorted by absolute values
// e.g. absoluteSort([-5,-1,3,6]) => [-1,3,-5,6]
export function absoluteSort(
inputArray: Entries<ScoreObj>[],
reversed = false
) {
const result = new Array(inputArray.length);
let i = 0;
let j = inputArray.length - 1;
let k = inputArray.length - 1;
while (i <= j) {
const firstKeyVal = inputArray[i];
const lastKeyVal = inputArray[j];
const firstVal = Math.abs(firstKeyVal[1]);
const lastVal = Math.abs(lastKeyVal[1]);
if (firstVal > lastVal) {
result[k] = firstKeyVal;
i++;
} else {
result[k] = lastKeyVal;
j--;
}
k--;
}
return reversed ? result.reverse() : result;
}
// sort an object of type {[key: string]: number}
// passing useAbsoluteValues will do absolute value sort
export function sortObj(
obj: ScoreObj,
useAbsoluteValues: boolean = false,
reversed = false,
numRendered?: number
) {
const sortedArr = objectEntries<ScoreObj>(obj)
.sort(([, a]: [string, number], [, b]: [string, number]) => {
return a - b;
})
.slice(0, numRendered);
let ret = {};
if (useAbsoluteValues) {
ret = objectify(absoluteSort(sortedArr, reversed));
} else {
ret = objectify(reversed ? sortedArr.reverse() : sortedArr);
}
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment