Skip to content

Commit

Permalink
refactor(arrays): add support for typed arrays
Browse files Browse the repository at this point in the history
- add function overrides to support typed arrays for:
  - argSort()
  - bisect(), bisectWith()
  - floydRivest()
  • Loading branch information
postspectacular committed Mar 28, 2024
1 parent 5f4db56 commit 1383916
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 20 deletions.
11 changes: 9 additions & 2 deletions packages/arrays/src/arg-sort.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Comparator } from "@thi.ng/api";
import { compare } from "@thi.ng/compare/compare";
import { fillRange } from "./fill-range.js";
import { sortByCachedKey } from "./sort-cached.js";
Expand Down Expand Up @@ -35,5 +36,11 @@ import { sortByCachedKey } from "./sort-cached.js";
* @param src -
* @param cmp -
*/
export const argSort = <T>(src: T[], cmp = compare) =>
sortByCachedKey(fillRange(new Array(src.length)), src.slice(), cmp);
export const argSort = <T>(src: Iterable<T>, cmp: Comparator<T> = compare) => {
const $src = [...src];
return sortByCachedKey(
fillRange(new Array<number>($src.length)),
$src,
cmp
);
};
27 changes: 17 additions & 10 deletions packages/arrays/src/bisect.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import type { Predicate } from "@thi.ng/api";
import type { Predicate, TypedArray } from "@thi.ng/api";

/**
* Splits array at given index (default: floor(src.length/2)) and returns tuple of [lhs, rhs].
* Splits array at given index (default: floor(src.length/2)) and returns tuple
* of [lhs, rhs].
*
* @param src -
* @param i -
* @param index -
*/
export const bisect = <T>(src: T[], i = src.length >>> 1) => [
src.slice(0, i),
src.slice(i),
];
export function bisect<T>(src: T[], index?: number): [T[], T[]];
export function bisect<T extends TypedArray>(src: T, index?: number): [T, T];
export function bisect(src: any[] | TypedArray, index = src.length >>> 1) {
return [src.slice(0, index), src.slice(index)];
}

/**
* Similar to {@link bisect}, but first finds split index via provided
Expand All @@ -20,7 +22,12 @@ export const bisect = <T>(src: T[], i = src.length >>> 1) => [
* @param src -
* @param pred -
*/
export const bisectWith = <T>(src: T[], pred: Predicate<T>) => {
export function bisectWith<T>(src: T[], pred: Predicate<T>): [T[], T[]];
export function bisectWith<T extends TypedArray>(
src: T,
pred: Predicate<number>
): [T, T];
export function bisectWith(src: any[] | TypedArray, pred: Predicate<any>) {
const i = src.findIndex(pred);
return i >= 0 ? bisect(src, i) : [src, []];
};
return i >= 0 ? bisect(<any>src, i) : [src, src.slice(0, 0)];
}
4 changes: 2 additions & 2 deletions packages/arrays/src/fill-range.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { TypedArray } from "@thi.ng/api";
import type { NumericArray } from "@thi.ng/api";

/**
* Fills given array with values in [start .. end) interval from `index`
Expand Down Expand Up @@ -29,7 +29,7 @@ import type { TypedArray } from "@thi.ng/api";
* @param end -
* @param step -
*/
export const fillRange = <T extends number[] | TypedArray>(
export const fillRange = <T extends NumericArray>(
buf: T,
index = 0,
start = 0,
Expand Down
26 changes: 20 additions & 6 deletions packages/arrays/src/floyd-rivest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Comparator } from "@thi.ng/api";
import type { Comparator, TypedArray } from "@thi.ng/api";
import { compare } from "@thi.ng/compare/compare";
import { swap } from "./swap.js";

Expand Down Expand Up @@ -33,13 +33,27 @@ import { swap } from "./swap.js";
* @param left
* @param right
*/
export const floydRivest = <T>(
export function floydRivest<T>(
buf: T[],
k?: number,
cmp?: Comparator<T>,
left?: number,
right?: number
): T[];
export function floydRivest<T extends TypedArray>(
buf: T,
k?: number,
cmp?: Comparator<number>,
left?: number,
right?: number
): T;
export function floydRivest(
buf: any[] | TypedArray,
k = 1,
cmp: Comparator<T> = compare,
cmp: Comparator<any> = compare,
left = 0,
right = buf.length - 1
) => {
) {
while (right > left) {
// constants 600 & 0.5 are from original paper
if (right - left > 600) {
Expand All @@ -50,7 +64,7 @@ export const floydRivest = <T>(
const sd =
0.5 * Math.sqrt(z * s * ((n - s) / n)) * Math.sign(i - n / 2);
floydRivest(
buf,
<any>buf,
k,
cmp,
Math.max(left, (k - (i * s) / n + sd) | 0),
Expand Down Expand Up @@ -84,4 +98,4 @@ export const floydRivest = <T>(
if (k <= j) right = j - 1;
}
return buf;
};
}

0 comments on commit 1383916

Please sign in to comment.