2019-01-21 10:57:11 -05:00
|
|
|
/** Copyright 2014-2019 Stewart Allen -- All Rights Reserved */
|
2017-04-18 22:22:29 -04:00
|
|
|
|
2017-04-18 17:09:33 -04:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
(function() {
|
|
|
|
|
var AP = Array.prototype;
|
|
|
|
|
|
|
|
|
|
/** ******************************************************************
|
2020-11-11 14:40:15 -05:00
|
|
|
* Array prototype helpers
|
2017-04-18 17:09:33 -04:00
|
|
|
******************************************************************* */
|
|
|
|
|
|
2020-03-21 19:13:20 -04:00
|
|
|
if (!AP.flat) {
|
|
|
|
|
AP.flat = function() {
|
|
|
|
|
return [].concat.apply([], this);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-21 14:55:51 -04:00
|
|
|
AP.equals = function(arr) {
|
|
|
|
|
if (!arr) return false;
|
|
|
|
|
if (arr.length !== this.length) return false;
|
|
|
|
|
for (let i=0; i<this.length; i++) {
|
|
|
|
|
if (arr[i] !== this[i]) return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-18 17:09:33 -04:00
|
|
|
AP.peek = function() {
|
|
|
|
|
return this[this.length-1];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* allow chaining of push() calls
|
|
|
|
|
*
|
|
|
|
|
* @param v
|
|
|
|
|
* @returns {Array}
|
|
|
|
|
*/
|
2020-11-02 10:32:53 -05:00
|
|
|
AP.append = function(v, flat) {
|
|
|
|
|
if (flat) {
|
|
|
|
|
return this.appendAll(v);
|
|
|
|
|
} else {
|
|
|
|
|
this.push(v);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2017-04-18 17:09:33 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* append all array elements to this array
|
|
|
|
|
*
|
|
|
|
|
* @param {Array} arr
|
|
|
|
|
* @returns {Array}
|
|
|
|
|
*/
|
|
|
|
|
AP.appendAll = function(arr) {
|
2020-11-27 14:42:55 -05:00
|
|
|
if (arr && arr.length > 0) {
|
|
|
|
|
// avoid hitting stack limits
|
|
|
|
|
if (arr.length > 10000) {
|
|
|
|
|
for (let i=0, il=arr.length; i<il; i++) {
|
|
|
|
|
this.push(arr[i]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// this.push.apply(this,arr); (slower?)
|
|
|
|
|
this.push(...arr);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-18 17:09:33 -04:00
|
|
|
return this;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* shallow cloning with clone(arg) call on each new element
|
|
|
|
|
*
|
|
|
|
|
* @param {Array} [arg]
|
|
|
|
|
* @returns {Array}
|
|
|
|
|
*/
|
|
|
|
|
AP.clone = function(arg) {
|
|
|
|
|
var na = this.slice(),
|
|
|
|
|
ln = na.length,
|
|
|
|
|
i = 0;
|
|
|
|
|
while (i < ln) na[i] = na[i++].clone(arg);
|
|
|
|
|
return na;
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-10 19:56:34 -05:00
|
|
|
AP.xray = function(arg) {
|
|
|
|
|
const na = [], ln = this.length;
|
|
|
|
|
for (let i=0; i<ln; i++) {
|
|
|
|
|
na.push(this[i].xray(arg));
|
|
|
|
|
}
|
|
|
|
|
return na;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
AP.xout = function(label, inset) {
|
|
|
|
|
if (label) console.log(`${label} [${this.length}]`);
|
|
|
|
|
if (!inset) inset = ' ';
|
|
|
|
|
this.forEach((el,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);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-18 17:09:33 -04:00
|
|
|
/**
|
|
|
|
|
* 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;
|
|
|
|
|
};
|
|
|
|
|
|
2020-12-01 00:02:34 -05:00
|
|
|
AP.removeAll = function(array) {
|
|
|
|
|
for (let i=0, il=array.length; i<il; i++) {
|
|
|
|
|
this.remove(array[i]);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-18 17:09:33 -04:00
|
|
|
/**
|
|
|
|
|
* return last array element if array length > 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]());
|
|
|
|
|
})
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-01 00:22:07 -05:00
|
|
|
AP.uniq = function() {
|
|
|
|
|
return this.slice().sort().filter((x, i, a) => !i || x != a[i-1]);
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-18 17:09:33 -04:00
|
|
|
/** ******************************************************************
|
2020-11-11 14:40:15 -05:00
|
|
|
* String prototype helpers
|
2017-04-18 17:09:33 -04:00
|
|
|
******************************************************************* */
|
|
|
|
|
|
|
|
|
|
String.prototype.reverse = function() {
|
|
|
|
|
return this.split('').reverse().join('');
|
|
|
|
|
};
|
|
|
|
|
|
2020-04-13 17:42:40 -04:00
|
|
|
/** ******************************************************************
|
|
|
|
|
* Object static helpers
|
|
|
|
|
******************************************************************* */
|
|
|
|
|
|
|
|
|
|
Object.clone = function(o) {
|
|
|
|
|
return o ? JSON.parse(JSON.stringify(o)) : o;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Math.bound = function(val,min,max) {
|
|
|
|
|
return Math.max(min,Math.min(max,val));
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-11 14:40:15 -05:00
|
|
|
/** ******************************************************************
|
|
|
|
|
* Number static helpers
|
|
|
|
|
******************************************************************* */
|
|
|
|
|
|
|
|
|
|
Number.prototype.round = function(digits) {
|
|
|
|
|
const pow = Math.pow(10,digits || 3);
|
|
|
|
|
return Math.round(this.valueOf() * pow) / pow;
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-18 17:09:33 -04:00
|
|
|
})();
|