@amaui/heap
Version:
335 lines (287 loc) • 14.1 kB
JavaScript
/** @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 });
}));