@tidyjs/tidy
Version:
Tidy up your data with JavaScript, inspired by dplyr and the tidyverse
77 lines (74 loc) • 2.27 kB
JavaScript
import { ascending } from 'd3-array';
import { singleOrArray } from './helpers/singleOrArray.js';
function arrange(comparators) {
const _arrange = (items) => {
const comparatorFns = singleOrArray(comparators).map((comp) => typeof comp === "function" ? comp.length === 1 ? asc(comp) : comp : asc(comp));
return items.slice().sort((a, b) => {
for (const comparator of comparatorFns) {
const result = comparator(a, b);
if (result)
return result;
}
return 0;
});
};
return _arrange;
}
function asc(key) {
const keyFn = typeof key === "function" ? key : (d) => d[key];
return function _asc(a, b) {
return emptyAwareComparator(keyFn(a), keyFn(b), false);
};
}
function desc(key) {
const keyFn = typeof key === "function" ? key : (d) => d[key];
return function _desc(a, b) {
return emptyAwareComparator(keyFn(a), keyFn(b), true);
};
}
function fixedOrder(key, order, options) {
let {position = "start"} = options != null ? options : {};
const positionFactor = position === "end" ? -1 : 1;
const indexMap = new Map();
for (let i = 0; i < order.length; ++i) {
indexMap.set(order[i], i);
}
const keyFn = typeof key === "function" ? key : (d) => d[key];
return function _fixedOrder(a, b) {
var _a, _b;
const aIndex = (_a = indexMap.get(keyFn(a))) != null ? _a : -1;
const bIndex = (_b = indexMap.get(keyFn(b))) != null ? _b : -1;
if (aIndex >= 0 && bIndex >= 0) {
return aIndex - bIndex;
}
if (aIndex >= 0) {
return positionFactor * -1;
}
if (bIndex >= 0) {
return positionFactor * 1;
}
return 0;
};
}
function emptyAwareComparator(aInput, bInput, desc2) {
let a = desc2 ? bInput : aInput;
let b = desc2 ? aInput : bInput;
if (isEmpty(a) && isEmpty(b)) {
const rankA = a !== a ? 0 : a === null ? 1 : 2;
const rankB = b !== b ? 0 : b === null ? 1 : 2;
const order = rankA - rankB;
return desc2 ? -order : order;
}
if (isEmpty(a)) {
return desc2 ? -1 : 1;
}
if (isEmpty(b)) {
return desc2 ? 1 : -1;
}
return ascending(a, b);
}
function isEmpty(value) {
return value == null || value !== value;
}
export { arrange, asc, desc, fixedOrder };
//# sourceMappingURL=arrange.js.map