-
Notifications
You must be signed in to change notification settings - Fork 188
/
Copy pathrank.js
24 lines (23 loc) · 942 Bytes
/
rank.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import ascending from "./ascending.js";
import {ascendingDefined, compareDefined} from "./sort.js";
export default function rank(values, valueof = ascending) {
if (typeof values[Symbol.iterator] !== "function") throw new TypeError("values is not iterable");
let V = Array.from(values);
const R = new Float64Array(V.length);
if (valueof.length !== 2) V = V.map(valueof), valueof = ascending;
const compareIndex = (i, j) => valueof(V[i], V[j]);
let k, r;
values = Uint32Array.from(V, (_, i) => i);
// Risky chaining due to Safari 14 https://github.com/d3/d3-array/issues/123
values.sort(valueof === ascending ? (i, j) => ascendingDefined(V[i], V[j]) : compareDefined(compareIndex));
values.forEach((j, i) => {
const c = compareIndex(j, k === undefined ? j : k);
if (c >= 0) {
if (k === undefined || c > 0) k = j, r = i;
R[j] = r;
} else {
R[j] = NaN;
}
});
return R;
}