Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 137x | /**
* The default instance order of a split, in the comparator pattern of OHIF
* `sortStudy.ts`: a null-safe {@link compare} of one value, and comparators
* that compare one key and fall back to the next comparator with `||`. Each
* comparator has the signature of `SplitRule.compareInstances`, and passes
* `context` down the chain.
*
* @module displayset/sortInstances
*/
import { toFiniteFirst } from '@cornerstonejs/utils';
import type { NaturalizedInstance, RuleContext } from './types';
/**
* Compares two values: equal (`==`) is 0, and a value with no truth (absent,
* `''`, `0`) sorts before a value with one. Else `<` decides.
*/
export function compare(a: unknown, b: unknown): number {
if (a == b) {
return 0;
}
if (!a && b) {
return -1;
}
if (!b && a) {
return 1;
}
return (a as string) < (b as string) ? -1 : 1;
}
/**
* Compares by `SOPInstanceUID`, else `imageId`, as text. The last step of the
* default order, so the order is total.
*/
export function compareSOPInstanceUID(
a: NaturalizedInstance,
b: NaturalizedInstance,
_context?: RuleContext
): number {
return compare(
String(a.SOPInstanceUID ?? a.imageId ?? ''),
String(b.SOPInstanceUID ?? b.imageId ?? '')
);
}
/**
* Compares by `InstanceNumber` only; 0 when the numbers are equal, or when
* both are absent. An absent or non-numeric `InstanceNumber` sorts after the
* numbered instances, and does not alias to 0 (`toFiniteFirst`, not `Number`).
*/
export function compareInstanceNumber(
a: NaturalizedInstance,
b: NaturalizedInstance,
_context?: RuleContext
): number {
const aNumber = toFiniteFirst(a.InstanceNumber);
const bNumber = toFiniteFirst(b.InstanceNumber);
return aNumber !== undefined && bNumber !== undefined
? aNumber - bNumber
: Number(aNumber === undefined) - Number(bNumber === undefined);
}
/**
* The default instance order: {@link compareInstanceNumber}, then
* {@link compareSOPInstanceUID}. `context` goes down the chain.
*/
export function sortByInstanceNumber(
a: NaturalizedInstance,
b: NaturalizedInstance,
context?: RuleContext
): number {
return (
compareInstanceNumber(a, b, context) || compareSOPInstanceUID(a, b, context)
);
}
/** The instance sort criteria, as in OHIF `sortStudy.ts`. */
export const instancesSortCriteria = {
default: sortByInstanceNumber,
sortByInstanceNumber,
};
/**
* Returns a sorted COPY of `instances`; the input array does not change. (OHIF
* `sortStudyInstances` sorts in place; a split must not change the caller's
* array.) A host gives its own comparator chain as `criteria`, and `context`
* goes to each call of it.
*/
export function sortInstancesCopy<T extends NaturalizedInstance>(
instances: readonly T[],
criteria: (
a: NaturalizedInstance,
b: NaturalizedInstance,
context?: RuleContext
) => number = instancesSortCriteria.default,
context?: RuleContext
): T[] {
return [...instances].sort((a, b) => criteria(a, b, context));
}
|