UNPKG

mauss

Version:

practical functions and reusable configurations

73 lines (72 loc) 2.43 kB
export const compare = { /** Compares nullish values, sorting `null` and `undefined` to the end */ undefined(x, y) { if (x == null && y == null) return 0; return (x == null && 1) || (y == null && -1) || 0; }, /** Compares boolean values, prioritizing `true` over `false` */ boolean(x, y) { return +y - +x; }, /** * Put `(x, y)` for bigger number first, and `(y, x)` for smaller number first * @returns `y - x` which defaults to descending order */ number(x, y) { return y - x; }, /** Compares bigint values, defaults to ascending order */ bigint(x, y) { return x < y ? -1 : x > y ? 1 : 0; }, /** Compares symbols using its string values */ symbol(x, y) { return x.toString().localeCompare(y.toString()); }, /** Compares string values using `.localeCompare` */ string(x, y) { return x.localeCompare(y); }, /** Compares generic object values using {@link inspect} */ object(x, y) { if (x === null) return 1; if (y === null) return -1; return inspect(x, y); }, }; /** Compares anything with anything */ export function wildcard(x, y) { if (x == null) return 1; if (y == null) return -1; const [xt, yt] = [typeof x, typeof y]; if (xt === 'function') return 0; if (xt !== yt || xt === 'object') { const xs = JSON.stringify(x); const ys = JSON.stringify(y); return compare.string(xs, ys); } return compare[xt](x, y); } /** * Recursively compares common object properties until the first difference is found * @returns `0` if both objects are identical or completely different, otherwise their respective primitive difference */ export function inspect(x, y) { const common = [...new Set([...Object.keys(x), ...Object.keys(y)])].filter((k) => k in x && k in y && typeof x[k] === typeof y[k] && x[k] !== y[k]); for (let i = 0, key = common[i], data = typeof x[key]; i < common.length && x[key] !== null && y[key] !== null; key = common[++i], data = typeof x[key]) { if (data === 'function') continue; if (data === 'object') return inspect(x[key], y[key]); const constrained = compare[data]; if (data in compare) return constrained(x[key], y[key]); } return 0; }