From f4d0c50a8b4480b013b99faafb4a2a69f1bd689f Mon Sep 17 00:00:00 2001 From: Angus MacDonald Date: Fri, 27 Nov 2020 14:00:41 -0600 Subject: [PATCH] Add arrayf.min function --- src/arrayf/arrayf.ts | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/arrayf/arrayf.ts b/src/arrayf/arrayf.ts index c53ee4696a..9b6b9749f8 100644 --- a/src/arrayf/arrayf.ts +++ b/src/arrayf/arrayf.ts @@ -28,5 +28,44 @@ export class arrayf { return output; } + /** + * Given a set of values and score functions returns the value with the + * lowest score. If two objects tie using the first score function then the + * next given score function (if any) is used to break the tie. + * ``` + * const values = [2.2, 2.1, 3.4]; + * const fnA = (x) => Math.floor(x); + * const fnB = (x) => x; + * arrayf.min(values, fnA); // Returns 2.2 + * arrayf.min(values, fnA, fnB); // Returns 2.1 + * ``` + */ + static min(values: T[], ...scoreFns: Array<(v: T) => number>): T { + let minValue: T; + let minScore: number = Number.POSITIVE_INFINITY; + + const scoreFn = scoreFns[0]; -} \ No newline at end of file + values.forEach((value) => { + const score = scoreFn(value); + if (minScore > score) { + minValue = value; + minScore = score; + } else if (minScore === score && scoreFns.length > 1) { + let i = 1; + let tieBreaker = scoreFns[i]; + while ( + i < scoreFns.length && + tieBreaker(minValue) === tieBreaker(value) + ) { + tieBreaker = scoreFns[i++]; + } + + if (tieBreaker(minValue) > tieBreaker(value)) { + minValue = value; + } + } + }); + return minValue; + } +}