UNPKG

@amaui/heap

Version:
335 lines (287 loc) 14.1 kB
/** @license AmauiHeap v1.0.11117 * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.AmauiHeap = {})); })(this, (function (exports) { 'use strict'; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var global$1 = (typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var is$1 = {exports: {}}; (function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); const optionsDefault = {}; const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined'; const isNodejs = !!(typeof global$1 !== 'undefined' && 'object' !== 'undefined' && module.exports); // Multiple is methods instead of one, // so it's lighter for tree shaking usability reasons function is(type, value, options_ = {}) { var _a; const options = Object.assign(Object.assign({}, optionsDefault), options_); const { variant } = options; const prototype = value && typeof value === 'object' && Object.getPrototypeOf(value); switch (type) { case 'string': return typeof value === 'string'; case 'number': return typeof value === 'number' && !Number.isNaN(value); case 'boolean': return typeof value === 'boolean'; case 'array': return Array.isArray(value); case 'object': const isObject = typeof value === 'object' && !!value && value.constructor === Object; return isObject; // Map, null, WeakMap, Date, etc. case 'object-like': return typeof value === 'object' && (value === null || value.constructor !== Object); case 'class': return ((typeof value === 'object' || typeof value === 'function') && (/class/gi.test(String(value)) || /class/gi.test(String(value === null || value === void 0 ? void 0 : value.constructor)))); case 'function': return !!(value && value instanceof Function); case 'async': // If it's browser avoid calling the method // to see if it's async func or not, // where as in nodejs we have no other choice // that i know of when using transpilation // And also it might not be always correct, as // a method that returns a promise is also async // but we can't know that until the method is called and // we inspect the method's return value return !!(is('function', value) && (isBrowser ? value.constructor.name === 'AsyncFunction' : value() instanceof Promise)); case 'map': return !!(prototype === Map.prototype); case 'weakmap': return !!(prototype === WeakMap.prototype); case 'set': return !!(prototype === Set.prototype); case 'weakset': return !!(prototype === WeakSet.prototype); case 'promise': return !!(prototype === Promise.prototype); case 'int8array': return !!(prototype === Int8Array.prototype); case 'uint8array': return !!(prototype === Uint8Array.prototype); case 'uint8clampedarray': return !!(prototype === Uint8ClampedArray.prototype); case 'int16array': return !!(prototype === Int16Array.prototype); case 'uint16array': return !!(prototype === Uint16Array.prototype); case 'int32array': return !!(prototype === Int32Array.prototype); case 'uint32array': return !!(prototype === Uint32Array.prototype); case 'float32array': return !!(prototype === Float32Array.prototype); case 'float64array': return !!(prototype === Float64Array.prototype); case 'bigint64array': return !!(prototype === BigInt64Array.prototype); case 'biguint64array': return !!(prototype === BigUint64Array.prototype); case 'typedarray': return is('int8array', value) || is('uint8array', value) || is('uint8clampedarray', value) || is('int16array', value) || is('uint16array', value) || is('int32array', value) || is('uint32array', value) || is('float32array', value) || is('float64array', value) || is('bigint64array', value) || is('biguint64array', value); case 'dataview': return !!(prototype === DataView.prototype); case 'arraybuffer': return !!(prototype === ArrayBuffer.prototype); case 'sharedarraybuffer': return typeof SharedArrayBuffer !== 'undefined' && !!(prototype === SharedArrayBuffer.prototype); case 'symbol': return !!(typeof value === 'symbol'); case 'error': return !!(value && value instanceof Error); case 'date': return !!(value && value instanceof Date); case 'regexp': return !!(value && value instanceof RegExp); case 'arguments': return !!(value && value.toString() === '[object Arguments]'); case 'null': return value === null; case 'undefined': return value === undefined; case 'blob': return isBrowser && value instanceof Blob; case 'buffer': return !!(isNodejs && typeof ((_a = value === null || value === void 0 ? void 0 : value.constructor) === null || _a === void 0 ? void 0 : _a.isBuffer) === 'function' && value.constructor.isBuffer(value)); case 'element': if (value) { switch (variant) { case undefined: case 'html': case 'element': return isBrowser && (typeof HTMLElement === 'object' ? value instanceof HTMLElement : value && typeof value === 'object' && value !== null && value.nodeType === 1 && typeof value.nodeName === 'string'); case 'node': return isBrowser && (typeof Node === 'object' ? value instanceof Node : value && typeof value === 'object' && value !== null && typeof value.nodeType === 'number' && typeof value.nodeName === 'string'); case 'react': return value.elementType || value.hasOwnProperty('$$typeof'); default: return false; } } return false; case 'simple': return (is('string', value, options) || is('number', value, options) || is('boolean', value, options) || is('undefined', value, options) || is('null', value, options)); case 'not-array-object': return !is('array', value, options) && !is('object', value, options); default: return false; } } exports.default = is; }(is$1, is$1.exports)); var is = /*@__PURE__*/getDefaultExportFromCjs(is$1.exports); class AmauiNode { constructor(value) { this.value = value; } } class AmauiHeap { static get min() { return new AmauiHeap('min'); } static get max() { return new AmauiHeap('max'); } static make(value, variant) { return new AmauiHeap(variant).make(value); } static left(index) { return 2 * index + 1; } static right(index) { return 2 * index + 2; } static parent(index) { return Math.floor((index - 1) / 2); } static isPriority(index) { return index === 0; } static isLeft(index) { return !!(index !== 0 && index % 2); } static isRight(index) { return !!(index !== 0 && !(index % 2)); } static isLeaf(index, values) { return index >= Math.floor(values.length / 2) && index <= values.length - 1; } constructor() { let variant = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'min'; this.variant = variant; _defineProperty(this, "values", []); } get array() { return this.values.map(item => item.value); } get first() { return this.values[0]; } get leafs() { return this.values.filter((_, index) => AmauiHeap.isLeaf(index, this.values)); } get remove() { if (!this.values.length) return; const first = this.first; const end = this.values.pop(); this.values[0] = end; // Heapify down first values value this.heapifyDown(); return first; } add(value) { const amauiNode = value instanceof AmauiNode ? value : new AmauiNode(value); // Push to the end of the values array this.values.push(amauiNode); // Heapify up the added values value this.heapifyUp(); return this; } swap(index, index1) { [this.values[index], this.values[index1]] = [this.values[index1], this.values[index]]; return this; } make(value) { this.values = value.map(value_ => value_ instanceof AmauiNode ? value_ : new AmauiNode(value_)); for (let i = Math.floor(this.values.length / 2); i >= 0; i--) { this.heapifyDown(i); } return this; } forEach(method) { if (is('function', method)) this.values.forEach((value, index) => { const parent = this.values[AmauiHeap.parent(index)]; const left = this.values[AmauiHeap.left(index)]; const right = this.values[AmauiHeap.right(index)]; const isPriority = AmauiHeap.isPriority(index); const isLeaf = AmauiHeap.isLeaf(index, this.values); const isLeft = AmauiHeap.isLeft(index); const isRight = AmauiHeap.isRight(index); method(value, index, parent, left, right, isPriority, isLeaf, isLeft, isRight); }); } heapifyUp() { let index_ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.values.length - 1; if (this.values.length > 0) { let index = index_; let parentIndex = AmauiHeap.parent(index); while (index > 0 && (this.variant === 'min' ? ((_this$values$parentIn = this.values[parentIndex]) === null || _this$values$parentIn === void 0 ? void 0 : _this$values$parentIn.value) > ((_this$values$index = this.values[index]) === null || _this$values$index === void 0 ? void 0 : _this$values$index.value) : ((_this$values$parentIn2 = this.values[parentIndex]) === null || _this$values$parentIn2 === void 0 ? void 0 : _this$values$parentIn2.value) < ((_this$values$index2 = this.values[index]) === null || _this$values$index2 === void 0 ? void 0 : _this$values$index2.value))) { var _this$values$parentIn, _this$values$index, _this$values$parentIn2, _this$values$index2; // Swap parent and child this.swap(parentIndex, index); index = parentIndex; parentIndex = AmauiHeap.parent(index); } } } heapifyDown() { let index_ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (!AmauiHeap.isLeaf(index_, this.values)) { var _this$values$left, _this$values$swapInde, _this$values$left2, _this$values$swapInde2, _this$values$right, _this$values$swapInde3, _this$values$right2, _this$values$swapInde4; const index = index_; const left = AmauiHeap.left(index); const right = AmauiHeap.right(index); let swapIndex = index; // Swap left and parent if swap to be made if (this.variant === 'min' ? ((_this$values$left = this.values[left]) === null || _this$values$left === void 0 ? void 0 : _this$values$left.value) < ((_this$values$swapInde = this.values[swapIndex]) === null || _this$values$swapInde === void 0 ? void 0 : _this$values$swapInde.value) : ((_this$values$left2 = this.values[left]) === null || _this$values$left2 === void 0 ? void 0 : _this$values$left2.value) > ((_this$values$swapInde2 = this.values[swapIndex]) === null || _this$values$swapInde2 === void 0 ? void 0 : _this$values$swapInde2.value)) swapIndex = left; // Swap right and parent if swap to be made if (this.variant === 'min' ? ((_this$values$right = this.values[right]) === null || _this$values$right === void 0 ? void 0 : _this$values$right.value) < ((_this$values$swapInde3 = this.values[swapIndex]) === null || _this$values$swapInde3 === void 0 ? void 0 : _this$values$swapInde3.value) : ((_this$values$right2 = this.values[right]) === null || _this$values$right2 === void 0 ? void 0 : _this$values$right2.value) > ((_this$values$swapInde4 = this.values[swapIndex]) === null || _this$values$swapInde4 === void 0 ? void 0 : _this$values$swapInde4.value)) swapIndex = right; if (index !== swapIndex) { this.swap(index, swapIndex); this.heapifyDown(swapIndex); } } } } exports.AmauiHeap = AmauiHeap; exports.AmauiNode = AmauiNode; Object.defineProperty(exports, '__esModule', { value: true }); }));