UNPKG

@platform/cell.schema

Version:

URI and database schemas for the `cell.os`.

109 lines (108 loc) 3.84 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.naturalCompare = void 0; var defaultAlphabetIndexMap = []; function naturalCompare(a, b, opts) { if (opts === void 0) { opts = {}; } if (typeof a !== 'string') { throw new TypeError("The first argument must be a string. Received type '".concat(typeof a, "'")); } if (typeof b !== 'string') { throw new TypeError("The second argument must be a string. Received type '".concat(typeof b, "'")); } var lengthA = a.length; var lengthB = b.length; var indexA = 0; var indexB = 0; var alphabetIndexMap = defaultAlphabetIndexMap; var firstDifferenceInLeadingZeros = 0; if (opts) { if (opts.caseInsensitive) { a = a.toLowerCase(); b = b.toLowerCase(); } if (opts.alphabet) { alphabetIndexMap = buildAlphabetIndexMap(opts.alphabet); } } while (indexA < lengthA && indexB < lengthB) { var charCodeA = a.charCodeAt(indexA); var charCodeB = b.charCodeAt(indexB); if (isNumberCode(charCodeA)) { if (!isNumberCode(charCodeB)) { return charCodeA - charCodeB; } var numStartA = indexA; var numStartB = indexB; while (charCodeA === 48 && ++numStartA < lengthA) { charCodeA = a.charCodeAt(numStartA); } while (charCodeB === 48 && ++numStartB < lengthB) { charCodeB = b.charCodeAt(numStartB); } if (numStartA !== numStartB && firstDifferenceInLeadingZeros === 0) { firstDifferenceInLeadingZeros = numStartA - numStartB; } var numEndA = numStartA; var numEndB = numStartB; while (numEndA < lengthA && isNumberCode(a.charCodeAt(numEndA))) { ++numEndA; } while (numEndB < lengthB && isNumberCode(b.charCodeAt(numEndB))) { ++numEndB; } var difference = numEndA - numStartA - numEndB + numStartB; if (difference !== 0) { return difference; } while (numStartA < numEndA) { difference = a.charCodeAt(numStartA++) - b.charCodeAt(numStartB++); if (difference !== 0) { return difference; } } indexA = numEndA; indexB = numEndB; continue; } if (charCodeA !== charCodeB) { if (charCodeA < alphabetIndexMap.length && charCodeB < alphabetIndexMap.length && alphabetIndexMap[charCodeA] !== -1 && alphabetIndexMap[charCodeB] !== -1) { return alphabetIndexMap[charCodeA] - alphabetIndexMap[charCodeB]; } return charCodeA - charCodeB; } ++indexA; ++indexB; } if (indexA < lengthA) return 1; if (indexB < lengthB) return -1; return firstDifferenceInLeadingZeros; } exports.naturalCompare = naturalCompare; var alphabetIndexMapCache = {}; function buildAlphabetIndexMap(alphabet) { var existingMap = alphabetIndexMapCache[alphabet]; if (existingMap !== undefined) { return existingMap; } var indexMap = []; var maxCharCode = alphabet.split('').reduce(function (maxCode, char) { return Math.max(maxCode, char.charCodeAt(0)); }, 0); for (var i = 0; i <= maxCharCode; i++) { indexMap.push(-1); } for (var i = 0; i < alphabet.length; i++) { indexMap[alphabet.charCodeAt(i)] = i; } alphabetIndexMapCache[alphabet] = indexMap; return indexMap; } function isNumberCode(code) { return code >= 48 && code <= 57; }