/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */ "use strict"; (function() { gapp.register('add.array'); let AP = {}; /** ****************************************************************** * Array prototype helpers ******************************************************************* */ if (!AP.flat) { AP.flat = function() { return [].concat.apply([], this); }; } AP.equals = function(arr) { if (!arr) return false; if (arr.length !== this.length) return false; for (let i=0; i 0) { // avoid hitting stack limits if (arr.length > 10000) { for (let i=0, il=arr.length; i { if (el.xout) { el.xout(null, inset + i + inset); } else if (el.xray) { const info = el.xray(); console.log(inset, info); Object.values(info).forEach(val => { if (val.xout) { val.xout(null, inset + inset); } }); } }); }; /** * remove and return element from array, if present * * @param val * @returns {*} */ AP.remove = function(val) { var idx = this.indexOf(val); if (idx >= 0) return this.splice(idx,1); return null; }; AP.removeAll = function(array) { for (let i=0, il=array.length; i 0 * * @returns {*} */ AP.last = function() { if (this.length === 0) return null; return this[this.length-1]; }; AP.contains = function(val) { return this.indexOf(val) >= 0; }; AP.toFloat32 = function() { var i = 0, f32 = new Float32Array(this.length); while (i < this.length) { f32[i] = this[i++]; } return f32; }; AP.forEachPair = function(fn, incr) { var scope = this, idx = 0, inc = incr || 2, len = scope.length; while (idx < len) { fn(scope[idx], scope[(idx+1)%len], idx); idx += inc; } }; AP.show = function(fn,f) { f = f || function(v) { console.log(v) }; this.forEach(function(av) { f(av[fn]()); }) }; AP.uniq = function() { return this.slice().sort().filter((x, i, a) => !i || x != a[i-1]); }; AP.hasNaN = function() { return this.filter(v => isNaN(v)).length > 0; }; // wrap a function and unroll the first parameter into // successive function calls if it is an array Array.handle = function(fn) { return function() { let args = [...arguments]; let val = args.shift(); if (Array.isArray(val)) { let rv = []; for (let v of val.slice()) { rv.push(fn(v, ...args)); } return rv; } else { return fn(val, ...args); } } }; for (let i in AP) { Object.defineProperty(Array.prototype, i, { value: AP[i], enumerable: false }); } /** ****************************************************************** * String prototype helpers ******************************************************************* */ String.prototype.reverse = function() { return this.split('').reverse().join(''); }; /** ****************************************************************** * Object static helpers ******************************************************************* */ Object.clone = function(o) { return o ? JSON.parse(JSON.stringify(o)) : o; }; Object.toArray = function(o) { let ret = []; for (let [key,value] of Object.entries(o)) { ret.push({key, value}); } return ret; }; Math.bound = function(val,min,max) { return Math.max(min,Math.min(max,val)); }; /** ****************************************************************** * Number static helpers ******************************************************************* */ Number.prototype.round = function(digits) { const pow = Math.pow(10,digits || 3); return Math.round(this.valueOf() * pow) / pow; }; })();