UNPKG

@itwin/core-bentley

Version:

Bentley JavaScript core components

236 lines • 11.5 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Ids */ Object.defineProperty(exports, "__esModule", { value: true }); exports.OrderedId64Iterable = void 0; const Assert_1 = require("./Assert"); /** A collection of **valid** [[Id64String]]s sorted in ascending order by the unsigned 64-bit integer value of the Ids. * This ordering is a requirement for several groups of APIs including [[CompressedId64Set]]. * When used as input to a function, duplicate Ids are ignored; when returned as a function output, no duplicates are present. * @see [[CompressedId64Set]] for a compact string representation of such an ordered collection. * @see [[OrderedId64Iterable.compare]] for a function that compares Ids based on this criterion. * @see [[OrderedId64Array]] for a mutable implementation. * @public */ var OrderedId64Iterable; (function (OrderedId64Iterable) { /** An ordered comparison of [[Id64String]]s suitable for use with sorting routines like * [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) and sorted containers * like [[SortedArray]] and [[Dictionary]]. The comparison compares the 64-bit numerical values of the two Ids, returning a negative number if lhs < rhs, * a positive number if lhs > rhs, or zero if lhs == rhs. * The default string comparison is fine (and more efficient) when numerical ordering is not required; use this instead if you want e.g., "0x100" to be greater than "0xf". * @see [[OrderedId64Iterable.sortArray]] for a convenient way to sort an array of Id64Strings. */ function compare(lhs, rhs) { if (lhs.length !== rhs.length) return lhs.length < rhs.length ? -1 : 1; // This is faster than localeCompare(). Unclear why there is no string.compare() - would be generally useful in // array sort functions... if (lhs !== rhs) return lhs < rhs ? -1 : 1; return 0; } OrderedId64Iterable.compare = compare; /** Sort an array of [[Id64String]]s **in-place** in ascending order by their 64-bit numerical values. * @see [[OrderedId64Iterable.compare]] for the comparison routine used. * @returns the input array. * @note This function returns its input for consistency with Javascript's * [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) method. * It **does not** create a **new** array. */ function sortArray(ids) { ids.sort((x, y) => compare(x, y)); return ids; } OrderedId64Iterable.sortArray = sortArray; /** Given two ordered collections of [[Id64String]]s, determine whether they are identical sets. Duplicate Ids are ignored. * @note If the inputs are not ordered as required by [[OrderedId64Iterable]], the results are unpredictable. */ function areEqualSets(ids1, ids2) { const leftIter = uniqueIterator(ids1); const rightIter = uniqueIterator(ids2); let leftState = leftIter.next(); let rightState = rightIter.next(); while (!leftState.done && !rightState.done) { const left = leftState.value; const right = rightState.value; if (0 !== compare(left, right)) return false; leftState = leftIter.next(); rightState = rightIter.next(); } if (leftState.done && rightState.done) return true; return false; } OrderedId64Iterable.areEqualSets = areEqualSets; /** Given an ordered collection of [[Id64String]]s, determine if it contains any Ids. * @param ids A well-formed, ordered collection of zero or more valid Ids. * @returns true if the input represents an empty set of Ids. The result is unspecified if the input does not meet the criteria for the input type. */ function isEmptySet(ids) { if (typeof ids === "string") return "" === ids; return true === ids[Symbol.iterator]().next().done; } OrderedId64Iterable.isEmptySet = isEmptySet; /** Given an ordered collection of [[Id64String]]s possibly containing duplicates, produce an ordered collection containing no duplicates. * @note If the inputs are not ordered as required by [[OrderedId64Iterable]], the results are unpredictable. */ function unique(ids) { return { [Symbol.iterator]: () => uniqueIterator(ids) }; } OrderedId64Iterable.unique = unique; /** Given an ordered collection of [[Id64String]]s possibly containing duplicates, produce an ordered iterator over the distinct Ids, eliminating duplicates. * @note If the inputs are not ordered as required by [[OrderedId64Iterable]], the results are unpredictable. */ function* uniqueIterator(ids) { const iter = ids[Symbol.iterator](); let state = iter.next(); let prev; while (!state.done) { const id = state.value; state = iter.next(); if (id !== prev) { prev = id; yield id; } } } OrderedId64Iterable.uniqueIterator = uniqueIterator; /** Given two ordered collections of [[Id64String]]s, produce a collection representing their union - i.e., the Ids that are present in either or both collections. * @note If the inputs are not ordered as required by [[OrderedId64Iterable]], the results are unpredictable. */ function union(ids1, ids2) { return { [Symbol.iterator]: () => unionIterator(ids1, ids2) }; } OrderedId64Iterable.union = union; /** Given two ordered collections of [[Id64String]]s, produce an iterator representing their intersection - i.e., the Ids that are present in both collections. * @note If the inputs are not ordered as required by [[OrderedId64Iterable]], the results are unpredictable. */ function intersection(ids1, ids2) { return { [Symbol.iterator]: () => intersectionIterator(ids1, ids2) }; } OrderedId64Iterable.intersection = intersection; /** Given two ordered collections of [[Id64String]]s, produce an iterator representing their difference - i.e., the Ids that are present in `ids1` but not present in `ids2`. * @note If the inputs are not ordered as required by [[OrderedId64Iterable]], the results are unpredictable. */ function difference(ids1, ids2) { return { [Symbol.iterator]: () => differenceIterator(ids1, ids2) }; } OrderedId64Iterable.difference = difference; /** Given two ordered collections of [[Id64String]]s, produce an iterator representing their union - i.e., the Ids that are present in either or both collections. * @note If the inputs are not ordered as required by [[OrderedId64Iterable]], the results are unpredictable. */ function* unionIterator(ids1, ids2) { const leftIter = ids1[Symbol.iterator](); const rightIter = ids2[Symbol.iterator](); let leftState = leftIter.next(); let rightState = rightIter.next(); let prev; while (!leftState.done || !rightState.done) { const left = leftState.done ? undefined : leftState.value; const right = rightState.done ? undefined : rightState.value; (0, Assert_1.assert)(undefined !== left || undefined !== right); if (undefined === left && undefined === right) break; let next; if (undefined === left) { (0, Assert_1.assert)(undefined !== right); next = right; rightState = rightIter.next(); } else if (undefined === right) { next = left; leftState = leftIter.next(); } else { const cmp = compare(left, right); if (cmp <= 0) { next = left; leftState = leftIter.next(); if (0 === cmp) rightState = rightIter.next(); } else { next = right; rightState = rightIter.next(); } } if (prev === next) continue; prev = next; yield next; } } OrderedId64Iterable.unionIterator = unionIterator; /** Given two ordered collections of [[Id64String]]s, produce an iterator representing their intersection - i.e., the Ids that are present in both collections. * @note If the inputs are not ordered as required by [[OrderedId64Iterable]], the results are unpredictable. */ function* intersectionIterator(ids1, ids2) { const leftIter = ids1[Symbol.iterator](); const rightIter = ids2[Symbol.iterator](); let leftState = leftIter.next(); let rightState = rightIter.next(); let prev; while (!leftState.done && !rightState.done) { const left = leftState.value; leftState = leftIter.next(); if (left === prev) continue; prev = left; let right = rightState.value; let cmp = compare(left, right); while (cmp > 0) { rightState = rightIter.next(); if (rightState.done) return; right = rightState.value; cmp = compare(left, right); } if (0 === cmp) yield left; } } OrderedId64Iterable.intersectionIterator = intersectionIterator; /** Given two ordered collections of [[Id64String]]s, produce an iterator representing their difference - i.e., the Ids that are present in `ids1` but not present in `ids2`. * @note If the inputs are not ordered as required by [[OrderedId64Iterable]], the results are unpredictable. */ function* differenceIterator(ids1, ids2) { const leftIter = ids1[Symbol.iterator](); const rightIter = ids2[Symbol.iterator](); let leftState = leftIter.next(); let rightState = rightIter.next(); let prev; while (!leftState.done) { const left = leftState.value; leftState = leftIter.next(); if (left === prev) continue; else if (rightState.done) { yield prev = left; continue; } let right = rightState.value; let cmp = compare(left, right); while (cmp > 0 && !rightState.done) { rightState = rightIter.next(); if (rightState.done) { yield prev = left; continue; } right = rightState.value; cmp = compare(left, right); } if (cmp < 0) yield prev = left; } } OrderedId64Iterable.differenceIterator = differenceIterator; })(OrderedId64Iterable || (exports.OrderedId64Iterable = OrderedId64Iterable = {})); //# sourceMappingURL=OrderedId64Iterable.js.map