import debug from 'debug'; import Math from './math.js'; const log = debug('helper:lib:info'); const error = debug('helper:lib:error'); /** Lib*/ export class Lib { constructor() { this.items = []; this._hooks = {}; this.lsdCountner = [ [] ] } /** returns a sorted array, alias for `lib.bubbleSort`*/ sortBy(...args) { return this.sortByBubble(...args); } /** returns sorted array *@param * {function} smallerThen - callback called with 2 args `(val1,val2) => {return *(val1.nr < val2.nr);}` * @param {array} items - unsorted array * @return {array} - sorted array */ sortByBubble(smallerThen, items = this.getArray()) { let sorted = false; do { sorted = false; for (let i = 1; i < items.length; i++) { if (smallerThen(items[i], items[i - 1])) { let tmp = items[i]; items[i] = items[i - 1]; items[i - 1] = tmp; sorted = true; } } } while (sorted); return items; } /** LSD sort an array* * @param {key} key - value.key - must be numeric * @param {array} items - option, unsorted array * @param {integer} maxDigitSymbols - max length of int * @return {array} items - sorted array */ sortByLsd(key, items = this.getArray(), maxDigitSymbols) { var mod = 10; var dev = 1; for (var i = 0; i < maxDigitSymbols; i++, dev *= 10, mod *= 10) { for (var j = 0; j < items.length; j++) { var bucket = parseInt((items[j][key] % mod) / dev); if (this.lsdCountner[bucket] == null) { this.lsdCountner[bucket] = []; } this.lsdCountner[bucket].push(items[j][key]); } var pos = 0; for (var j = 0; j < this.lsdCountner.length; j++) { var value = null; if (this.lsdCountner[j] != null) { while ((value = this.lsdCountner[j].shift()) != null) { items[pos++][key] = value; } } } } return items; } /** get by id *@param {String} id - id of item *@return {object} item - the selected **item** or `undefined` */ getById(id) { return this.getArray().filter((item) => (item.id === id))[0]; } /** get an array with all items @return {array} items - all visible **items** */ getArray() { return this.items.filter((item) => (!item._remove)); } /** add an item to the list * @param {object} item - item to add to list * @param {boolean} overwrite - overwrite or not? *will not throw* */ add(item, overwrite = false) { log("add item", item); if ("function" === typeof this._hooks['beforeAdd']) { item = this._hooks['beforeAdd'](item); } if ('undefined' === typeof item.id) { item.id = new Math().uuid(); } let existingItem = this.getById(item.id); if ("undefined" !== typeof existingItem) { if (overwrite) { existingItem = item; return existingItem; } else { return log('add duplicate', 'item with this id already exist overwrite != true'); } } else { this.items.push(item); return item; } } /** set a hook *@event beforeAdd */ setHook(type, fn) { log('setHook', type, fn); this._hooks[type] = fn; } /** mark a item as removed -> will not be in getArray but getArrayById * @param {String} id - id of item to remove */ remove(id) { log('remove item', id); this.getById(id)._remove = true; } /** cb fired on every item from `this.getArray` *@param {function} cb - `(item)=>{console.log(item)};` */ each(cb) { let items = this.getArray(); for (let i = items.length; i >= 0; i--) { if (items[i] && items[i].id !== null) { cb(items[i]); } } } } export default Lib;