- 1 :
/* eslint-disable @typescript-eslint/no-unused-vars */
- 2 :
/* eslint-disable @typescript-eslint/no-this-alias */
- 3 :
/* eslint-disable @typescript-eslint/triple-slash-reference */
- 4 :
/* eslint-disable prefer-rest-params */
- 5 :
/* eslint-disable no-prototype-builtins */
- 6 :
/// <reference path="./globals.d.ts" />
- 7 :
const _global = (typeof window != 'undefined' ? window : global) /* node */ as any;
- 8 :
- 9 :
/**
- 10 :
* Arrays
- 11 :
*/
- 12 :
interface Array<T> {
- 13 :
/**
- 14 :
* Unique Array
- 15 :
* @example
- 16 :
* var duplicate = [1,2,1,2,3,4,5,6];
- 17 :
* var unique = duplicate.unique(); // [1,2,3,4,5,6]
- 18 :
*/
- 19 :
unique: () => Array<T>;
- 20 :
- 21 :
/**
- 22 :
* Unique string array case insensitive but keep one case sensitive result
- 23 :
* @see {@link https://stackoverflow.com/a/48731445/6404439}
- 24 :
* @example
- 25 :
* console.log(['James', 'james', 'bob', 'JaMeS', 'Bob'].uniqueStringArray()); // ["JaMeS", "Bob"]
- 26 :
*/
- 27 :
uniqueStringArray: () => Array<string>;
- 28 :
- 29 :
/**
- 30 :
* Move item to another index
- 31 :
* @see {@link https://stackoverflow.com/a/70618791/6404439}
- 32 :
*/
- 33 :
move: (from: number, to: number) => Array<T>;
- 34 :
- 35 :
/**
- 36 :
* Unique array of objects by key
- 37 :
* @see {@link https://stackoverflow.com/a/51537887}
- 38 :
* @param key object key to check
- 39 :
* @param removeNull remove null and undefined (default=true)
- 40 :
*/
- 41 :
uniqueObjectKey: (key: string, removeNull?: boolean) => Array<T>;
- 42 :
- 43 :
/**
- 44 :
* Remove array item from other arrays
- 45 :
*/
- 46 :
hapusItemDariArrayLain: (...arrayLain: any[]) => any[];
- 47 :
- 48 :
/**
- 49 :
* Pick 1 random array element
- 50 :
*/
- 51 :
random: <T>() => T;
- 52 :
- 53 :
/**
- 54 :
* split array to chunks
- 55 :
* @param size divided array by number index
- 56 :
*/
- 57 :
split_chunks: (size: number) => ReturnType<typeof array_split_chunks>;
- 58 :
- 59 :
/**
- 60 :
* Add Element
- 61 :
* @param element
- 62 :
* @example
- 63 :
* var a = [1,2];
- 64 :
* a.add(3);
- 65 :
* console.log(a); // [1,2,3]
- 66 :
*
- 67 :
* var b = [0,9];
- 68 :
* console.log(b.add(2)); // [0,9,2]
- 69 :
*/
- 70 :
add(element: any): Array<T>;
- 71 :
- 72 :
/**
- 73 :
* @summary Add another array
- 74 :
* @description Add another array to current array
- 75 :
* @param anotherArray
- 76 :
* @example
- 77 :
* var a = [0,1];
- 78 :
* var b = ['a','b'];
- 79 :
* console.log(b.addAll(a)); // ['a','b',0,1]
- 80 :
* var c = ['z',10];
- 81 :
* c.addAll(b);
- 82 :
* console.log(c); // ['z',10,'a','b',0,1]
- 83 :
* var d = ['last']:
- 84 :
* d.addAll(a,b,c);
- 85 :
* console.log(d); // ['last','a','b',0,1]
- 86 :
*/
- 87 :
addAll(...anotherArray: Array<any>): Array<any>;
- 88 :
- 89 :
/**
- 90 :
* Get element in range from array
- 91 :
* @param start start number index
- 92 :
* @param end end number index
- 93 :
* @example
- 94 :
* const arr = [1, 2, 3, 4, 5];
- 95 :
* console.log(arr.range(1, 3));
- 96 :
*/
- 97 :
range(start: number, end: number): Array<any>;
- 98 :
- 99 :
/**
- 100 :
* Returns true if self contains no elements.
- 101 :
* @see {@link Array<T>.length}
- 102 :
*/
- 103 :
isEmpty(): boolean;
- 104 :
- 105 :
/**
- 106 :
* Returns the first element, or the first n elements, of the array.
- 107 :
* If the array is empty, requesting one element returns undefined ,
- 108 :
* and requesting multiple elements returns an empty array.
- 109 :
* @example
- 110 :
* var a = [ "q", "r", "s", "t" ]
- 111 :
* a.first() // => "q"
- 112 :
* a.first(2) // => ["q", "r"]
- 113 :
*/
- 114 :
first(n: number): Array<T>;
- 115 :
- 116 :
/**
- 117 :
* Returns the last element(s) of self.
- 118 :
* If the array is empty, returns undefined if only one element requested.
- 119 :
* @example
- 120 :
* var a = [ "w", "x", "y", "z" ]
- 121 :
* a.last() // => "z"
- 122 :
* a.last(2) // => ["y", "z"]
- 123 :
*/
- 124 :
last(n: number): Array<T>;
- 125 :
- 126 :
/**
- 127 :
* Unset element value from array
- 128 :
* @param n value element
- 129 :
* @example
- 130 :
* var arr = ['a','b','c'];
- 131 :
* arr.unset('c');
- 132 :
* console.log(arr); // ['a','b']
- 133 :
*/
- 134 :
unset(n: any): Array<T>;
- 135 :
- 136 :
/**
- 137 :
* Deletes the element at the specified index, returning that element, or undefined if the index is out of range.
- 138 :
* A negative index is counted from the end of the array, where -1 corresponds to the last element. Returns self
- 139 :
* for chaining purposes.
- 140 :
* @example
- 141 :
* var a = ["ant", "bat", "cat", "dog"]
- 142 :
* a.deleteAt(2) // => "cat"
- 143 :
* a // => ["ant", "bat", "dog"]
- 144 :
* a.deleteAt(99) // => undefined (because index 99 not found)
- 145 :
* if(a.deleteAt(1)) console.log('item with index 1 removed') // conditional
- 146 :
*/
- 147 :
deleteAt(n: number): Array<T>;
- 148 :
- 149 :
/**
- 150 :
* Removes null and undefined elements from the array, turning it into a dense array.
- 151 :
* Returns self for chaining purposes
- 152 :
*/
- 153 :
compact(): Array<T>;
- 154 :
- 155 :
/**
- 156 :
* Check element index exists
- 157 :
* @example
- 158 :
* ['a','b'].exists(1); //true
- 159 :
* ['a','b'].exists(4); //false
- 160 :
*/
- 161 :
exists(n: number): boolean;
- 162 :
- 163 :
/**
- 164 :
* Check array contains string/any
- 165 :
* @param obj
- 166 :
* @example
- 167 :
* alert([1, 2, 3].contains(2)); // => true
- 168 :
* alert([1, 2, 3].contains('2')); // => false
- 169 :
*/
- 170 :
contains(obj: any): boolean;
- 171 :
- 172 :
/**
- 173 :
* Check if array offset (index) exists
- 174 :
* @param n
- 175 :
* @example
- 176 :
* alert([{},'a','x'].hasIndex(2)); // => true - array has offset 2 is 'x'
- 177 :
* alert([{},'a','x'].hasIndex(3)); // => false
- 178 :
*/
- 179 :
hasIndex(n: number): boolean;
- 180 :
- 181 :
/**
- 182 :
* Shuffle arrays.
- 183 :
* @description Randomize array elements
- 184 :
* @example
- 185 :
* alert([1,2,3,4,5].shuffle())
- 186 :
*/
- 187 :
shuffle(): Array<T>;
- 188 :
- 189 :
/**
- 190 :
* Remove null, empty string, or undefined values
- 191 :
*/
- 192 :
removeEmpties(): Array<T>;
- 193 :
- 194 :
/**
- 195 :
* trim array of strings
- 196 :
*/
- 197 :
trim(): Array<string>;
- 198 :
- 199 :
/**
- 200 :
* same as Array<any>['forEach']
- 201 :
*/
- 202 :
each: Array<any>['forEach']; //T[]['forEach'];
- 203 :
}
- 204 :
- 205 :
Array.prototype.each = function (this: Array<any>) {
- 206 :
return this.forEach;
- 207 :
};
- 208 :
- 209 :
Array.prototype.shuffle = function () {
- 210 :
let i = this.length,
- 211 :
j: number,
- 212 :
temp: any;
- 213 :
if (i == 0) return this;
- 214 :
while (--i) {
- 215 :
j = Math.floor(Math.random() * (i + 1));
- 216 :
temp = this[i];
- 217 :
this[i] = this[j];
- 218 :
this[j] = temp;
- 219 :
}
- 220 :
return this;
- 221 :
};
- 222 :
- 223 :
Array.prototype.last = function (n) {
- 224 :
if (!n) {
- 225 :
if (this.length === 0) return undefined;
- 226 :
- 227 :
return this[this.length - 1];
- 228 :
} else {
- 229 :
let start = this.length - n;
- 230 :
if (start < 0) start = 0;
- 231 :
- 232 :
return this.slice(start, this.length);
- 233 :
}
- 234 :
};
- 235 :
- 236 :
Array.prototype.trim = function () {
- 237 :
return this.map((str) => {
- 238 :
if (typeof str == 'string') return str.trim();
- 239 :
});
- 240 :
};
- 241 :
- 242 :
Array.prototype.isEmpty = function () {
- 243 :
return this.length === 0;
- 244 :
};
- 245 :
- 246 :
Array.prototype.range = function (start, end) {
- 247 :
if (end < start) {
- 248 :
return [];
- 249 :
}
- 250 :
return this.slice(start, end + 1);
- 251 :
};
- 252 :
- 253 :
Array.prototype.add = function (element) {
- 254 :
this.push(element);
- 255 :
return this;
- 256 :
};
- 257 :
- 258 :
Array.prototype.addAll = function (...otherArrays) {
- 259 :
const self = this;
- 260 :
otherArrays.forEach(function (array) {
- 261 :
array.forEach((item) => {
- 262 :
self.push(item);
- 263 :
});
- 264 :
});
- 265 :
return self;
- 266 :
};
- 267 :
- 268 :
Array.prototype.random = function () {
- 269 :
return this[Math.floor(Math.random() * this.length)];
- 270 :
};
- 271 :
- 272 :
Array.prototype.unique = function (this: Array<any>) {
- 273 :
const a = this.concat();
- 274 :
for (let i = 0; i < a.length; ++i) {
- 275 :
for (let j = i + 1; j < a.length; ++j) {
- 276 :
if (a[i] === a[j]) a.splice(j--, 1);
- 277 :
}
- 278 :
}
- 279 :
- 280 :
return a;
- 281 :
};
- 282 :
- 283 :
Array.prototype.uniqueStringArray = function (this: Array<string>) {
- 284 :
const filter = new Map(this.map((s) => [s.toLowerCase(), s]));
- 285 :
return [...filter.values()];
- 286 :
};
- 287 :
- 288 :
Array.prototype.uniqueObjectKey = function (this: Array<Record<string, unknown>>, key, removeNull = true) {
- 289 :
if (!key) return this;
- 290 :
const resArr = [];
- 291 :
this.filter(function (item) {
- 292 :
const i = resArr.findIndex((x) => x[key] == item[key]);
- 293 :
if (i <= -1) {
- 294 :
if (removeNull) {
- 295 :
if (item[key]) resArr.push(item);
- 296 :
} else {
- 297 :
resArr.push(item);
- 298 :
}
- 299 :
}
- 300 :
return null;
- 301 :
});
- 302 :
return resArr;
- 303 :
};
- 304 :
- 305 :
Array.prototype.contains = function (obj) {
- 306 :
let i = this.length;
- 307 :
while (i--) {
- 308 :
if (this[i] === obj) {
- 309 :
return true;
- 310 :
}
- 311 :
}
- 312 :
return false;
- 313 :
};
- 314 :
- 315 :
Array.prototype.hasIndex = function (n: number) {
- 316 :
return typeof this[n] != 'undefined';
- 317 :
};
- 318 :
- 319 :
Array.prototype.first = function (n) {
- 320 :
if (!n) {
- 321 :
if (this.length === 0) return undefined;
- 322 :
- 323 :
return this[0];
- 324 :
} else {
- 325 :
if (this.length === 0) return [];
- 326 :
- 327 :
return this.slice(0, n);
- 328 :
}
- 329 :
};
- 330 :
- 331 :
Array.prototype.compact = function () {
- 332 :
//var changes = false;
- 333 :
for (let i = 0; i < this.length; i++) {
- 334 :
// If element is non-existent, undefined or null, remove it.
- 335 :
if (!this[i]) {
- 336 :
this.splice(i, 1);
- 337 :
i = i - 1;
- 338 :
//changes = true;
- 339 :
}
- 340 :
}
- 341 :
//if (!changes) return undefined;
- 342 :
- 343 :
return this;
- 344 :
};
- 345 :
- 346 :
Array.prototype.deleteAt = function <T>(this: T[], index): T {
- 347 :
if (index < 0) index = this.length + index;
- 348 :
- 349 :
// If element is non-existent, return undefined:
- 350 :
if (!this.hasOwnProperty(index)) return undefined;
- 351 :
- 352 :
const elem = this[index];
- 353 :
this.splice(index, 1);
- 354 :
return elem;
- 355 :
};
- 356 :
- 357 :
Array.prototype.unset = function (value) {
- 358 :
if (this.indexOf(value) != -1) {
- 359 :
// Make sure the value exists
- 360 :
this.splice(this.indexOf(value), 1);
- 361 :
}
- 362 :
return this;
- 363 :
};
- 364 :
- 365 :
Array.prototype.exists = function (n: number) {
- 366 :
return typeof this[n] !== 'undefined';
- 367 :
};
- 368 :
- 369 :
if (!Array.prototype.hasOwnProperty('every')) {
- 370 :
Array.prototype.every = function (fun: any /*, thisp */) {
- 371 :
'use strict';
- 372 :
const t: { [x: string]: any; length: number } = Object(this);
- 373 :
const len = t.length >>> 0;
- 374 :
let i: string | number;
- 375 :
const thisp: any = arguments[1];
- 376 :
- 377 :
if (this == null) {
- 378 :
throw new TypeError();
- 379 :
}
- 380 :
- 381 :
if (typeof fun !== 'function') {
- 382 :
throw new TypeError();
- 383 :
}
- 384 :
- 385 :
for (i = 0; i < len; i++) {
- 386 :
if (i in t && !fun.call(thisp, t[i], i, t)) {
- 387 :
return false;
- 388 :
}
- 389 :
}
- 390 :
- 391 :
return true;
- 392 :
};
- 393 :
}
- 394 :
- 395 :
Array.prototype.move = function (from, to) {
- 396 :
const itemRemoved = this.splice(from, 1); // splice() returns the remove element as an array
- 397 :
this.splice(to, 0, itemRemoved[0]); // Insert itemRemoved into the target index
- 398 :
return this;
- 399 :
};
- 400 :
- 401 :
Array.prototype.hapusItemDariArrayLain = function (this: any[], ...arrayLain) {
- 402 :
let thisArr = this;
- 403 :
arrayLain.forEach((otherArr) => {
- 404 :
thisArr = thisArr.filter(function (el) {
- 405 :
return !otherArr.includes(el);
- 406 :
});
- 407 :
});
- 408 :
- 409 :
return thisArr;
- 410 :
};
- 411 :
- 412 :
Array.prototype.removeEmpties = function (this: any[]) {
- 413 :
const filter = this.filter(function (el: string | any) {
- 414 :
const notnull =
- 415 :
// make sure element is not null
- 416 :
el != null &&
- 417 :
// make sure element is not undefined
- 418 :
typeof el != 'undefined';
- 419 :
// if element is string, make sure string length not zero
- 420 :
if (typeof el == 'string') {
- 421 :
return notnull && el.trim().length > 0;
- 422 :
}
- 423 :
return notnull;
- 424 :
});
- 425 :
return filter;
- 426 :
};
- 427 :
- 428 :
/**
- 429 :
* split array to chunks
- 430 :
* @param sourceArray
- 431 :
* @param chunkSize
- 432 :
* @see {@link https://stackoverflow.com/a/71483760/6404439}
- 433 :
* @returns
- 434 :
* @example
- 435 :
let ar1 = [
- 436 :
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
- 437 :
];
- 438 :
// split array by 4
- 439 :
console.log("Split in chunks with 4 size", splitChunks(ar1, 4)); // [[1,2,3,4], [5,6,7,8]...]
- 440 :
*/
- 441 :
function array_split_chunks<T extends any[]>(sourceArray: T, chunkSize: number): T[] {
- 442 :
if (chunkSize <= 0) throw 'chunkSize must be greater than 0';
- 443 :
const result = [];
- 444 :
for (let i = 0; i < sourceArray.length; i += chunkSize) {
- 445 :
result[i / chunkSize] = sourceArray.slice(i, i + chunkSize);
- 446 :
}
- 447 :
return result;
- 448 :
}
- 449 :
_global.array_split_chunks = array_split_chunks;
- 450 :
Array.prototype.split_chunks = function (size) {
- 451 :
return array_split_chunks(this, size);
- 452 :
};
- 453 :
- 454 :
function array_filter(array: []) {
- 455 :
return array.filter(function (el) {
- 456 :
return el != null;
- 457 :
});
- 458 :
}
- 459 :
_global.array_filter = array_filter;
- 460 :
- 461 :
/**
- 462 :
* pick random from array
- 463 :
* @param {Array<any>} arrays
- 464 :
* @param {boolean} unique Unique the arrays
- 465 :
*/
- 466 :
function array_rand(arrays: any[], unique: any) {
- 467 :
if (unique) {
- 468 :
arrays = array_unique(arrays);
- 469 :
}
- 470 :
const index = Math.floor(Math.random() * arrays.length);
- 471 :
return {
- 472 :
index: index,
- 473 :
value: arrays[index],
- 474 :
};
- 475 :
}
- 476 :
_global.array_rand = array_rand;
- 477 :
- 478 :
/**
- 479 :
* Array unique
- 480 :
* @param {Array<any>} arrays
- 481 :
*/
- 482 :
function array_unique(arrays: any[]) {
- 483 :
return arrays.filter(function (item: any, pos: any, self: string | any[]) {
- 484 :
return self.indexOf(item) == pos;
- 485 :
});
- 486 :
}
- 487 :
_global.array_unique = array_unique;
- 488 :
- 489 :
/**
- 490 :
* Unset array
- 491 :
* @param {Array<any>} arrayName
- 492 :
* @param {String|number} key
- 493 :
*/
- 494 :
// eslint-disable-next-line @typescript-eslint/no-unused-vars
- 495 :
function array_unset(arrayName: { [x: string]: any }, key: any) {
- 496 :
let x: string | number;
- 497 :
const tmpArray = [];
- 498 :
for (x in arrayName) {
- 499 :
if (x != key) {
- 500 :
tmpArray[x] = arrayName[x];
- 501 :
}
- 502 :
}
- 503 :
return tmpArray;
- 504 :
}
- 505 :
_global.array_unset = array_unset;
- 506 :
- 507 :
/**
- 508 :
* PHP shuffle array equivalent
- 509 :
* @param array
- 510 :
* @example
- 511 :
* var arr = [2, 11, 37, 42];
- 512 :
* shuffle(arr);
- 513 :
* console.log(arr); //return random
- 514 :
*/
- 515 :
// eslint-disable-next-line @typescript-eslint/no-unused-vars
- 516 :
function shuffle(array: Array<any>) {
- 517 :
let currentIndex = array.length,
- 518 :
temporaryValue: any,
- 519 :
randomIndex: number;
- 520 :
- 521 :
// While there remain elements to shuffle...
- 522 :
while (0 !== currentIndex) {
- 523 :
// Pick a remaining element...
- 524 :
randomIndex = Math.floor(Math.random() * currentIndex);
- 525 :
currentIndex -= 1;
- 526 :
- 527 :
// And swap it with the current element.
- 528 :
temporaryValue = array[currentIndex];
- 529 :
array[currentIndex] = array[randomIndex];
- 530 :
array[randomIndex] = temporaryValue;
- 531 :
}
- 532 :
- 533 :
return array;
- 534 :
}
- 535 :
_global.shuffle = shuffle;
- 536 :
- 537 :
function arrayCompare(a1: Array<any>, a2: Array<any>) {
- 538 :
if (a1.length != a2.length) return false;
- 539 :
const length = a2.length;
- 540 :
for (let i = 0; i < length; i++) {
- 541 :
if (a1[i] !== a2[i]) return false;
- 542 :
}
- 543 :
return true;
- 544 :
}
- 545 :
_global.arrayCompare = arrayCompare;
- 546 :
- 547 :
/**
- 548 :
* in_array PHP equivalent
- 549 :
* @param needle string etc
- 550 :
* @param haystack
- 551 :
*/
- 552 :
function inArray(needle: any, haystack: Array<any>) {
- 553 :
const length = haystack.length;
- 554 :
for (let i = 0; i < length; i++) {
- 555 :
if (typeof haystack[i] == 'object') {
- 556 :
if (arrayCompare(haystack[i], needle)) return true;
- 557 :
} else {
- 558 :
if (haystack[i] == needle) return true;
- 559 :
}
- 560 :
}
- 561 :
return false;
- 562 :
}
- 563 :
- 564 :
/**
- 565 :
* in_array PHP equivalent
- 566 :
* @param needle string etc
- 567 :
* @param haystack
- 568 :
*/
- 569 :
function in_array(needle: any, haystack: Array<any>) {
- 570 :
return inArray(needle, haystack);
- 571 :
}
- 572 :
_global.in_array = in_array;
- 573 :
- 574 :
/**
- 575 :
* get all keys
- 576 :
* @param haystack string etc
- 577 :
*/
- 578 :
function array_keys(haystack: any) {
- 579 :
return Object.keys(haystack);
- 580 :
}
- 581 :
- 582 :
/**
- 583 :
* Shuffles array in place.
- 584 :
* @param a items An array containing the items.
- 585 :
*/
- 586 :
function array_shuffle(a: Array<any>) {
- 587 :
let j: number, x: any, i: number;
- 588 :
for (i = a.length - 1; i > 0; i--) {
- 589 :
j = Math.floor(Math.random() * (i + 1));
- 590 :
x = a[i];
- 591 :
a[i] = a[j];
- 592 :
a[j] = x;
- 593 :
}
- 594 :
return a;
- 595 :
}
- 596 :
_global.array_shuffle = array_shuffle;
- 597 :
- 598 :
/**
- 599 :
* Deep merge two or more objects into the first.
- 600 :
* (c) 2021 Chris Ferdinandi, MIT License, {@link https://gomakethings.com}
- 601 :
* @param objects The objects to merge together
- 602 :
* @returns Merged values of defaults and options
- 603 :
*/
- 604 :
function deepAssign(...objects: Record<any, unknown>[]): Record<any, unknown> {
- 605 :
// Make sure there are objects to merge
- 606 :
const len = objects.length;
- 607 :
if (len < 1) return;
- 608 :
if (len < 2) return objects[0];
- 609 :
- 610 :
// Merge all objects into first
- 611 :
for (let i = 1; i < len; i++) {
- 612 :
for (const key in objects[i]) {
- 613 :
if (objects[i].hasOwnProperty(key)) {
- 614 :
// If it's an object, recursively merge
- 615 :
// Otherwise, push to key
- 616 :
if (Object.prototype.toString.call(objects[i][key]) === '[object Object]') {
- 617 :
objects[0][key] = deepAssign(<any>objects[0][key] || {}, <any>objects[i][key]);
- 618 :
} else {
- 619 :
objects[0][key] = objects[i][key];
- 620 :
}
- 621 :
}
- 622 :
}
- 623 :
}
- 624 :
- 625 :
return arguments[0];
- 626 :
}
- 627 :
_global.deepAssign = deepAssign;
- 628 :
- 629 :
/**
- 630 :
* Remove item from array
- 631 :
* @param arr
- 632 :
* @param value
- 633 :
* @returns
- 634 :
*/
- 635 :
function removeItem<T>(arr: Array<T>, value: T): Array<T> {
- 636 :
const index = arr.indexOf(value);
- 637 :
if (index > -1) {
- 638 :
arr.splice(index, 1);
- 639 :
}
- 640 :
return arr;
- 641 :
}
- 642 :
_global.removeItem = removeItem;