Skip to content

Commit

Permalink
feat(strings): add int/intLocale, vector formatters
Browse files Browse the repository at this point in the history
- add optional arg for float() for special NaN/Inf handling
  • Loading branch information
postspectacular committed Jan 31, 2021
1 parent 4302f58 commit ac55fe0
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 6 deletions.
15 changes: 9 additions & 6 deletions packages/strings/src/float.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ import type { Stringer } from "./api";
import { padLeft } from "./pad-left";

/**
* Returns {@link Stringer} which formats numbers to given precision.
* Exceptions:
* Returns {@link Stringer} which formats numbers to given precision. If
* `special` is true, then exceptional handling for:
*
* - NaN => "NaN"
* - Infinity => "+/-∞"
*
* @param len - number of fractional digits
* @kind function
* @param special - true, if special handling for NaN/Infinity values
*/
export const float: (
prec: number
) => Stringer<number> = memoizeJ((prec) => (x: number) =>
nanOrInf(x) || x.toFixed(prec)
prec: number,
special?: boolean
) => Stringer<number> = memoizeJ((prec, special = false) =>
special
? (x: number) => nanOrInf(x) || x.toFixed(prec)
: (x: number) => x.toFixed(prec)
);

/**
Expand Down
2 changes: 2 additions & 0 deletions packages/strings/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * from "./float";
export * from "./format";
export * from "./groups";
export * from "./hollerith";
export * from "./int";
export * from "./interpolate";
export * from "./join";
export * from "./pad-left";
Expand All @@ -28,5 +29,6 @@ export * from "./truncate";
export * from "./truncate-left";
export * from "./units";
export * from "./uuid";
export * from "./vector";
export * from "./wrap";
export * from "./word-wrap";
10 changes: 10 additions & 0 deletions packages/strings/src/int.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { memoizeJ } from "@thi.ng/memoize";
import type { Stringer } from "./api";

export const int: Stringer<number> = (x) => String(Math.trunc(x));

export const intLocale: (
locale?: string
) => Stringer<number> = memoizeJ((locale) => (x) =>
Math.trunc(x).toLocaleString(locale)
);
55 changes: 55 additions & 0 deletions packages/strings/src/vector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { isNumber } from "@thi.ng/checks";
import { memoizeJ } from "@thi.ng/memoize";
import type { Stringer } from "./api";
import { float } from "./float";

/**
* Higher order formatter for n-D vectors, with each element formatted using
* `prec` and using optional delimiter and pre/postfixes.
*
* @size - vector size (optimized for size 1-4)
* @prec - precision (see {@link float}) or existing number formatter
* @delim - delimiter (default: `,`)
* @pre - prefix (default: `[`)
* @post - prefix (default: `]`)
*/
export const vector: (
size: number,
prec?: number | Stringer<number>,
delim?: string,
pre?: string,
post?: string
) => Stringer<ArrayLike<number>> = memoizeJ(
(
size: number,
prec: number | Stringer<number> = 3,
d = ",",
pre = "[",
post = "]"
) => {
const f = isNumber(prec) ? float(prec) : prec;
switch (size) {
case 1:
return (v: ArrayLike<number>) => `${pre}${f(v[0])}${post}`;
case 2:
return (v: ArrayLike<number>) =>
`${pre}${f(v[0])}${d}${f(v[1])}${post}`;
case 3:
return (v: ArrayLike<number>) =>
`${pre}${f(v[0])}${d}${f(v[1])}${d}${f(v[2])}${post}`;
case 4:
return (v: ArrayLike<number>) =>
`${pre}${f(v[0])}${d}${f(v[1])}${d}${f(v[2])}${d}${f(
v[3]
)}${post}`;
default:
return (v: ArrayLike<number>) => {
const res = [];
for (let i = 0; i < v.length; i++) {
res.push(f(v[i]));
}
return `${pre}${res.join(d)}${post}`;
};
}
}
);

0 comments on commit ac55fe0

Please sign in to comment.