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