Created
July 26, 2022 16:47
-
-
Save olegchursin/c3c905c3117ef235ffd0f823aa6cb9b1 to your computer and use it in GitHub Desktop.
Object utils
This file contains 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
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