UNPKG

typescript-map

Version:
320 lines (319 loc) 9.27 kB
"use strict"; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TSMap = void 0; var TSMap = /** @class */ (function () { function TSMap(inputMap) { var t = this; t._keys = []; t._values = []; t.length = 0; if (inputMap) { inputMap.forEach(function (v, k) { t.set(v[0], v[1]); }); } } /** * Convert a JSON object to a map. * * @param {*} jsonObject JSON object to convert * @param {boolean} [convertObjs] convert nested objects to maps * @returns {TSMap<K, V>} * @memberof TSMap */ TSMap.prototype.fromJSON = function (jsonObject, convertObjs) { var t = this; var setProperty = function (value) { if (value !== null && typeof value === 'object' && convertObjs) return new TSMap().fromJSON(value, true); if (Array.isArray(value) && convertObjs) return value.map(function (v) { return setProperty(v); }); return value; }; Object.keys(jsonObject).forEach(function (property) { if (jsonObject.hasOwnProperty(property)) { t.set(property, setProperty(jsonObject[property])); } }); return t; }; /** * Outputs the contents of the map to a JSON object * * @returns {{[key: string]: V}} * @memberof TSMap */ TSMap.prototype.toJSON = function () { var obj = {}; var t = this; var getValue = function (value) { if (value instanceof TSMap) { return value.toJSON(); } else if (Array.isArray(value)) { return value.map(function (v) { return getValue(v); }); } else { return value; } }; t.keys().forEach(function (k) { obj[String(k)] = getValue(t.get(k)); }); return obj; }; /** * Get an array of arrays respresenting the map, kind of like an export function. * * @returns {(Array<Array<K|V>>)} * * @memberOf TSMap */ TSMap.prototype.entries = function () { var _this = this; return [].slice.call(this.keys().map(function (k) { return [k, _this.get(k)]; })); }; /** * Get an array of keys in the map. * * @returns {Array<K>} * * @memberOf TSMap */ TSMap.prototype.keys = function () { return [].slice.call(this._keys); }; /** * Get an array of the values in the map. * * @returns {Array<V>} * * @memberOf TSMap */ TSMap.prototype.values = function () { return [].slice.call(this._values); }; /** * Check to see if an item in the map exists given it's key. * * @param {K} key * @returns {Boolean} * * @memberOf TSMap */ TSMap.prototype.has = function (key) { return this._keys.indexOf(key) > -1; }; /** * Get a specific item from the map given it's key. * * @param {K} key * @returns {V} * * @memberOf TSMap */ TSMap.prototype.get = function (key) { var i = this._keys.indexOf(key); return i > -1 ? this._values[i] : undefined; }; /** * Safely retrieve a deeply nested property. * * @param {K[]} path * @returns {V} * * @memberOf TSMap */ TSMap.prototype.deepGet = function (path) { if (!path || !path.length) return null; var recursiveGet = function (obj, path) { if (obj === undefined || obj === null) return null; if (!path.length) return obj; return recursiveGet(obj instanceof TSMap ? obj.get(path[0]) : obj[path[0]], path.slice(1)); }; return recursiveGet(this.get(path[0]), path.slice(1)); }; /** * Set a specific item in the map given it's key, automatically adds new items as needed. * Ovewrrites existing items * * @param {K} key * @param {V} value * * @memberOf TSMap */ TSMap.prototype.set = function (key, value) { var t = this; // check if key exists and overwrite var i = this._keys.indexOf(key); if (i > -1) { t._values[i] = value; } else { t._keys.push(key); t._values.push(value); t.length = t._values.length; } return this; }; /** * Enters a value into the map forcing the keys to always be sorted. * Stolen from https://machinesaredigging.com/2014/04/27/binary-insert-how-to-keep-an-array-sorted-as-you-insert-data-in-it/ * Best case speed is O(1), worse case is O(N). * * @param {K} key * @param {V} value * @param {number} [startVal] * @param {number} [endVal] * @returns {this} * @memberof TSMap */ TSMap.prototype.sortedSet = function (key, value, startVal, endVal) { var t = this; var length = this._keys.length; var start = startVal || 0; var end = endVal !== undefined ? endVal : length - 1; if (length == 0) { t._keys.push(key); t._values.push(value); return t; } if (key == this._keys[start]) { this._values[start] = value; return this; } if (key == this._keys[end]) { this._values[end] = value; return this; } if (key > this._keys[end]) { this._keys.splice(end + 1, 0, key); this._values.splice(end + 1, 0, value); return this; } if (key < this._keys[start]) { this._values.splice(start, 0, value); this._keys.splice(start, 0, key); return this; } if (start >= end) { return this; } var m = start + Math.floor((end - start) / 2); if (key < this._keys[m]) { return this.sortedSet(key, value, start, m - 1); } if (key > this._keys[m]) { return this.sortedSet(key, value, m + 1, end); } return this; }; /** * Provide a number representing the number of items in the map * * @returns {number} * * @memberOf TSMap */ TSMap.prototype.size = function () { return this.length; }; /** * Clear all the contents of the map * * @returns {TSMap<K,V>} * * @memberOf TSMap */ TSMap.prototype.clear = function () { var t = this; t._keys.length = t.length = t._values.length = 0; return this; }; /** * Delete an item from the map given it's key * * @param {K} key * @returns {Boolean} * * @memberOf TSMap */ TSMap.prototype.delete = function (key) { var t = this; var i = t._keys.indexOf(key); if (i > -1) { t._keys.splice(i, 1); t._values.splice(i, 1); t.length = t._keys.length; return true; } return false; }; /** * Used to loop through the map. * * @param {(value:V,key?:K,index?:number) => void} callbackfn * * @memberOf TSMap */ TSMap.prototype.forEach = function (callbackfn) { var _this = this; this._keys.forEach(function (v, i) { callbackfn(_this.get(v), v, i); }); }; /** * Returns an array containing the returned value of each item in the map. * * @param {(value:V,key?:K,index?:number) => any} callbackfn * @returns {Array<any>} * * @memberOf TSMap */ TSMap.prototype.map = function (callbackfn) { var _this = this; return this.keys().map(function (itemKey, i) { return callbackfn(_this.get(itemKey), itemKey, i); }); }; /** * Removes items based on a conditional function passed to filter. * Mutates the map in place. * * @param {(value:V,key?:K,index?:number) => Boolean} callbackfn * @returns {TSMap<K,V>} * * @memberOf TSMap */ TSMap.prototype.filter = function (callbackfn) { var t = this; __spreadArrays(t._keys).forEach(function (v, i) { if (callbackfn(t.get(v), v, i) === false) t.delete(v); }); return this; }; /** * Creates a deep copy of the map, breaking all references to the old map and it's children. * Uses JSON.parse so any functions will be stringified and lose their original purpose. * * @returns {TSMap<K,V>} * * @memberOf TSMap */ TSMap.prototype.clone = function () { return new TSMap(this.entries()); }; return TSMap; }()); exports.TSMap = TSMap;