Passed
Push — master ( 2ebd67...097df7 )
by Night
01:12
created

arrayFuncs.indexOfNot   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 1
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
/** global: UB */
2
/** global: Buffer */
3
4
/*! ARRAY UTILS */
5
6
var arrayFuncs = {
7
8
	merge: function(){
9
		var arr = this;
10
		var val1 = arr[0];
11
12
		// if array of strings
13
		if (val1.isString()){
14
			return val1.join("");
15
		}
16
17
		// if array of arrays
18
		if (val1.isArray()){
19
			var merged = [];
20
			for (var a = 0, al = arr.length; a<al; a++){
21
				merged.addArray(arr[a]);
22
			}
23
			return merged;
24
		}
25
26
		// if array of Buffers
27
		//removeIf(nodejs)
28
		if (val1 instanceof Buffer){
29
30
			// calc the total length of all buffers
31
			var buffers = arr;
32
			var len = 0;
33
			for(var b = 0, bl = buffers.length; b < bl; b++) {
34
				len += buffers[b].length;
35
			}
36
37
			// create a new buffer of that length
38
			var mega = new Buffer(len);
39
40
			// write all buffers into the mega buffer
41
			var cur = 0;
42
			for(var b = 0, bl = buffers.length; b < bl; b++) {
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable bl already seems to be declared on line 33. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable b already seems to be declared on line 33. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
43
				buffers[b].copy(mega, cur, 0);
44
				cur += buffers[b].length;
45
			}
46
			return mega;
47
		}
48
		//endRemoveIf(nodejs)
49
50
		return null;
51
	},
52
	
53
	indexOf: function(value){
54
		var list = this;
55
		if (list.length === 0) {
56
			return -1;
57
		}
58
		for (var a = 0, al = list.length;a<al;a++){
59
			if (list[a] == value){
60
				return a;
61
			}
62
		}
63
		return -1;
64
	},
65
	indexOfNot: function(value){
66
		var list = this;
67
		if (list.length === 0) {
68
			return -1;
69
		}
70
		for (var a = 0, al = list.length;a<al;a++){
71
			if (list[a] != value){
72
				return a;
73
			}
74
		}
75
		return -1;
76
	},
77 View Code Duplication
	lastIndexOf: function(value){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
78
		var list = this;
79
		if (list.length === 0) {
80
			return -1;
81
		}
82
		for (var a = list.length-1;a>=0;a--){
83
			if (list[a] == value){
84
				return a;
85
			}
86
		}
87
		return -1;
88
	},
89 View Code Duplication
	lastIndexOfNot: function(value){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
90
		var list = this;
91
		if (list.length === 0) {
92
			return -1;
93
		}
94
		for (var a = list.length-1;a>=0;a--){
95
			if (list[a] != value){
96
				return a;
97
			}
98
		}
99
		return -1;
100
	},
101
	
102 View Code Duplication
	count: function(value, not = false){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
103
		var list = this;
104
		var total = 0;
105
		for (var a = 0, al = list.length;a<al;a++){
106
			if (not) {
107
				if (list[a] != value) {
108
					total++;
109
				}
110
			}else {
111
				if (list[a] == value) {
112
					total++;
113
				}
114
			}
115
		}
116
		return total;
117
	},
118
	or: function(list2){
119
		var list = this;
120
		if (Exists(list)) {
121
			return list;
122
		}
123
		return list2;
124
	},
125
	
126
	part: function(start, end){
127
		var list = this;
128
		
129
		// quickly exit if no items or no results possible
130
		if (list == null || list.length === 0 || start > end || start >= list.length) {
131
			return [];
132
		}
133
		
134
		// just get the part we need
135
		return list.slice(start, end + 1);
136
	},
137
	
138
	swap: function(slot1, slot2){
139
		var list = this;
140
		var temp = list[slot2];
141
		list[slot2] = list[slot1];
142
		list[slot1] = temp;
143
	},
144
145
	add: function(item){
146
		var list = this;
147
		list.push(item);
148
		return list.length - 1;
149
	},
150
	addToStart: function(item){
151
		var list = this;
152
		list.unshift(item);
153
		return 0;
154
	},
155
	/** return false if item exists, true if item does not */
156
	addOnce: function(value){
157
		var list = this;
158
		
159
		// return false if item exists
160
		if (list.indexOf(value) > -1) {
161
			return false;
162
		}
163
		
164
		// add if not found
165
		list.push(value);
166
		return true;
167
	},
168
	
169
	addArray: function(toAdd, addAtSlot = -1, modifyMain = true){
170
		var list = this;
171
		
172
		if (toAdd != null && toAdd.length > 0) {
173
			if (!modifyMain) {
174
				list = list.concat(); /// shallow clone
175
			}
176
			
177
			// set length first so allocates memory (maybe?)
178
			var origLen = list.length;
179
			if (addAtSlot === -1){
180
				list.length += toAdd.length;
181
			}
182
			
183
			// set all slots
184
			var next = addAtSlot === -1 ? origLen : addAtSlot;
185
			for (var a = 0, al = toAdd.length;a<al;a++, next++){
186
				list[next] = toAdd[a];
187
			}
188
		}
189
		return list;
190
	},
191
	
192
	/** adds the given value many times */
193
	addManyTimes: function(val, times){
194
		var list = this;
195
		
196
		if (times <= 0) {
197
			return list;
198
		}
199
		
200
		var n = list.length;
201
		for (var t = 0;t<times;t++){
202
			list[n++] = val;
203
		}
204
		
205
		return list;
206
	},
207
	
208
	addRange: function(toAdd, startSlot, endSlot){
209
		var list = this;
210
		
211
		// exit if no work
212
		if (endSlot < startSlot) {
213
			return;
214
		}
215
		
216
		// per wanted slot of the `add` array
217
		startSlot = startSlot.limitToArray(toAdd);
218
		endSlot = endSlot.limitToArray(toAdd);
219
		for (var s = startSlot;s <= endSlot;s++){
220
			
221
			// add into `main` array
222
			list.push(toAdd[s]);
223
			
224
		}
225
	},
226
	
227
	/** returns final index of added item, or index of already existing item */
228
	findOrAdd: function(value){
229
		var list = this;
230
		
231
		// return index of item if exists
232
		var i = list.indexOf(value);
233
		if (i > -1) {
234
			return i;
235
		}
236
		
237
		// add if not found
238
		i = list.length;
239
		list[i] = value;
240
		return i;
241
	},
242
	
243
	insertOne: function(item, slot){
244
		var list = this;
245
		
246
		// adds one slot at the given point
247
		// modifies the main array
248
		
249
		list.splice(slot, 0, item);
250
	},
251
252
	/** if slot = -1 or outside the array, the item is added to the END of the array.
253
	 * Otherwise the item is added at the given slot. */
254
	insertOneOrAdd: function(item, slot){
255
		var list = this;
256
		
257
		// adds one slot at the given point
258
		// modifies the main array
259
		
260
		if (slot < 0 || slot >= list.length) {
261
			list.push(item);
262
			return list.length - 1;
263
		}
264
		list.splice(slot, 0, item);
265
		return slot;
266
	},
267
	insertArray: function(newItems, slot, returnNew = true){
268
		var list = this;
269
		
270
		// adds many slots at the given point
271
		// returns a new array
272
		if(returnNew){
273
			return list.slice(0, slot).concat(newItems).concat(list.slice(slot));
274
		}
275
		
276
		// adds many slots at the given point
277
		// modifies the main array
278
		for (var a = 0, al = newItems.length;a<al;a++){
279
			list.splice(slot++, 0, newItems[a]);
280
		}
281
		return list;
282
	},
283
	insertArrayAfter: function(newItems, after){
284
		var list = this;
285
		if (list.isLast(after)) {
286
			list.addArray(newItems);
287
		} else {
288
			var i = list.indexOf(after);
289
			list.insertArray(i + 1, newItems);
290
		}
291
	},
292
	
293
294
	removeAndInsert: function(from, to){
295
		var list = this;
296
		
297
		// ensure slots within array
298
		var al = list.length;
299
		from = from.limitTo(0, al - 1);
300
		to = to.limitTo(0, al - 1);
301
		if (to < from) {
302
			var i1 = to;
303
			var i2 = from;
304
		}else {
305
			i1 = from;
306
			i2 = to;
307
		}
308
		
309
		// fill unaffected header
310
		var result = [];
311
		if(i1 > 0){
312
			for (var a = 0;a<i1;a++){
313
				result[a] = list[a];
314
			}
315
		}
316
		
317
		// fill "to"
318
		result[to] = list[from];
319
		
320
		// fill between from and to
321
		if(to < from){
322
			for (a = to + 1; a <= from; a++) {
323
				result[a] = list[a - 1];
324
			}
325
		}else {
326
			for (a = from; a < to; a++) {
327
				result[a] = list[a + 1];
328
			}
329
		}
330
		
331
		// fill unaffected footer
332
		for (var a = i2 + 1;a<al;a++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable a already seems to be declared on line 312. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
333
			result[a] = list[a];
334
		}
335
		
336
		return result;
337
	},
338
	
339
	/** replace a range of items with a given array */
340
	replaceRange: function(replaceStartSlot, replaceEndSlot, newItems, returnNew = true){
341
		var list = this;
342
		
343
		
344
		// simply remove a single item
345
		if (replaceStartSlot == replaceEndSlot && newItems.length === 0) {
346
			if (returnNew) {
347
				list = list.concat();
348
			}
349
			list.splice(replaceStartSlot, 1);
350
			return list;
351
			
352
		// simply replace a single item
353
		}else if (replaceStartSlot == replaceEndSlot && newItems.length === 1) {
354
			if (returnNew) {
355
				list = list.concat();
356
			}
357
			list[replaceStartSlot] = newItems[0];
358
			return list;
359
			
360
		}
361
		
362
		// alt method if returning a new array
363
		if(returnNew){
364
			return list.slice(0, replaceStartSlot).concat(newItems).concat(list.slice(replaceEndSlot + 1));
365
		}
366
		
367
		// remove many
368
		list.splice(replaceStartSlot, (replaceEndSlot - replaceStartSlot) + 1);
369
		
370
		// insert many
371
		var slot = replaceStartSlot;
372
		for (var a = 0, al = newItems.length;a<al;a++){
373
			list.splice(slot++, 0, newItems[a]);
374
		}
375
		return list;
376
	},
377
	
378
	replace: function(find, replace, stringReplace = false){
379
		var list = this;
380
		for (var i = 0, il = list.length;i<il;i++){
381
			if (stringReplace){
382
383
				// replace substring within string items
384
				var str = list[i];
385
				if (str && str.constructor === String) {
386
					list[i] = str.replaceAll(find, replace);
387
				}
388
			}else{
389
390
				// replace entire items
391
				if (list[i] == find) {
392
					list[i] = replace;
393
				}
394
			}
395
		}
396
	},
397
	replaceOnce: function(find, replace){
398
		var list = this;
399
		for (var i = 0, il = list.length;i<il;i++){
400
			if (list[i] == find) {
401
				list[i] = replace;
402
				return;
403
			}
404
		}
405
	},
406
	replaceMany: function(findArray, replaceArray){
407
		var list = this;
408
		if (findArray.length != replaceArray.length){
409
			return;
410
		}
411
		for (var i = 0, il = list.length;i<il;i++){
412
			for (var f = 0, fl = findArray.length;f<fl;f++){
413
				var find = findArray[f];
414
				if (list[i] == find) {
415
					list[i] = replaceArray[f];
416
					break;
417
				}
418
			}
419
		}
420
	},
421
	
422
	
423
	remove: function(value, stringReplace = false){
424
		var list = this;
425
		for (var i = 0, il = list.length;i<il;i++){
426
			if (stringReplace){
427
428
				// remove substring within string items
429
				var str = list[i];
430
				if (str && str.constructor === String) {
431
					list[i] = str.removeAll(value);
432
				}
433
			}else{
434
435
				// remove entire items
436
				if (list[i] == value) {
437
					list.splice(i, 1);
438
					i--;
439
					il--;
440
				}
441
			}
442
		}
443
	},
444
	removeOnce: function(val){
445
		var list = this;
446
		var i = list.indexOf(val);
447
		if (i > -1) {
448
			list.splice(i, 1);
449
		}
450
		return i;
451
	},
452
	removeFirst: function(returnNew = false){
453
		var list = this;
454
455
		// return new
456
		if (returnNew) {
457
			return list.slice(1);
458
		}
459
460
		// modify existing
461
		if (list.length > 0) {
462
			list.splice(0, 1);
463
		}
464
		return list;
465
	},
466
	removeFirstX: function(count, returnNew = false){
467
		var list = this;
468
		
469
		// if fewer items than wanted, clear entire array
470
		if (list.length < count) {
471
			if (returnNew) {
472
				return [];
473
			}
474
			list.length = 0;
475
			return list;
476
		}
477
		
478
		// delete X items from start
479
		// return new
480
		if (returnNew) {
481
			return list.slice(count);
482
		}
483
484
		// modify existing
485
		list.splice(0, count);
486
		return list;
487
	},
488
	removeLast: function(returnNew = false){
489
		var list = this;
490
491
		// return new
492
		if (returnNew) {
493
			return list.slice(0, list.length - 1);
494
		}
495
496
		// modify existing
497
		if (list.length > 0) {
498
			list.splice( - 1, 1);
499
		}
500
		return list;
501
	},
502
	removeLastX: function(count, returnNew = false){
503
		var list = this;
504
		
505
		// if fewer items than wanted, clear entire array
506
		if (list.length < count) {
507
			if (returnNew) {
508
				return [];
509
			}
510
			list.length = 0;
511
			return list;
512
		}
513
		
514
		// delete X items from end
515
		// return new
516
		if (returnNew) {
517
			return list.slice(0, list.length - count);
518
		}
519
		
520
		// modify existing
521
		list.splice( -count, count);
522
		return list;
523
	},
524
	
525
	removeEdges: function(fromLeftEdge, fromRightEdge){
526
		var list = this;
527
		if ((list.length - fromLeftEdge - fromRightEdge) <= 0) {
528
			return [];
529
		}
530
		return list.slice(fromLeftEdge, list.length - fromRightEdge);
531
	},
532
	
533
	removePart: function(start, end){
534
		var list = this;
535
		start = start.limitToArray(list);
536
		end = end.limitToArray(list);
537
		list.splice(start, (end-start)+1);
538
	},
539
	
540
	
541
	splitAt: function(slot, includeSlot = false, includeInFirst = false){
542
		var list = this;
543
		if (includeSlot) {
544
			if (includeInFirst) {
545
				return [list.slice(0, slot + 1), list.slice(slot + 1)];
546
			}
547
			return [list.slice(0, slot), list.slice(slot)];
548
		}
549
		return [list.slice(0, slot), list.slice(slot+1)];
550
	},
551
	splitAtEvery: function(val){
552
		var list = this;
553
		var splits = [];
554
		var lastSlot = 0;
555
		for (var a = 0, al = list.length;a<al;a++){
556
			if (list[a] == val && a > lastSlot) {
557
				splits.push(list.slice(lastSlot, a));
558
				lastSlot = a + 1;
559
			}
560
		}
561
		return splits;
562
	},
563
	
564
	moveToTop: function(slot, returnNew = false){
565
		var list = this;
566
567 View Code Duplication
		if (returnNew){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
568
569
			// ALWAYS RETURNS NEW ARRAY
570
			
571
			// exit quickly if slot not in array
572
			var al = list.length;
573
			if (slot < 0 || slot >= al) {
574
				return list.concat();
575
			}
576
			
577
			// create new array with slot on top
578
			var newArr = [list[slot]];
579
			var n = 1;
580
			
581
			// add all other slots
582
			for (var a = 0;a<al;a++){
583
				if (a != slot) {
584
					newArr[n++] = list[a];
585
				}
586
			}
587
588
			return newArr;
589
		}
590
591
592
		// MODIFIES ARRAY IN PLACE
593
		
594
		// exit quickly if slot not in array
595
		var al = list.length;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable al already seems to be declared on line 572. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
596
		if (slot < 0 || slot >= al) {
597
			return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
598
		}
599
		
600
		// delete and re-add slot
601
		var val = list[slot];
602
		list.splice(slot, 1);
603
		list.unshift(val);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
604
	},
605
	moveToBottom: function(slot, returnNew = false){
606
		var list = this;
607
608 View Code Duplication
		if (returnNew){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
609
610
			// ALWAYS RETURNS NEW ARRAY
611
			
612
			// exit quickly if slot not in array
613
			var al = list.length;
614
			if (slot < 0 || slot >= al) {
615
				return list.concat();
616
			}
617
			
618
			// create new array with slot on top
619
			var newArr = [];
620
			var n = 0;
621
			
622
			// add all other slots
623
			for (var a = 0;a<al;a++){
624
				if (a != slot) {
625
					newArr[n++] = list[a];
626
				}
627
			}
628
			
629
			// add slot to bottom
630
			newArr[n++] = list[slot];
0 ignored issues
show
Unused Code introduced by
The assignment to variable n seems to be never used. Consider removing it.
Loading history...
631
			return newArr;
632
633
		}
634
635
		// MODIFIES ARRAY IN PLACE
636
		
637
		// exit quickly if slot not in array
638
		var al = list.length;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable al already seems to be declared on line 613. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
639
		if (slot < 0 || slot >= al) {
640
			return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
641
		}
642
		
643
		// delete and re-add slot
644
		var val = list[slot];
645
		list.splice(slot, 1);
646
		list.push(val);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
647
	},
648
	moveUp: function(item){
649
		var list = this;
650
		
651
		// MODIFIES ARRAY IN PLACE
652
		
653
		// exit quickly if slot not in array, or already on top
654
		var slot = list.indexOf(item);
655
		if (slot <= 0) {
656
			return false;
657
		}
658
		
659
		// move one up
660
		list.swap(slot, slot - 1);
661
		return true;
662
	},
663
	moveDown: function(item){
664
		var list = this;
665
		
666
		// MODIFIES ARRAY IN PLACE
667
		
668
		// exit quickly if slot not in array, or already at bottom
669
		var al = list.length;
670
		var slot = list.indexOf(item);
671
		if (slot < 0 || slot >= (al - 1)) {
672
			return false;
673
		}
674
		
675
		// move one down
676
		list.swap(slot, slot + 1);
677
		return true;
678
	},
679
	moveSlotUp: function(slot){
680
		var list = this;
681
		
682
		// MODIFIES ARRAY IN PLACE
683
		
684
		// exit quickly if slot not in array, or already on top
685
		var al = list.length;
686
		if (slot <= 0 || slot >= al) {
687
			return false;
688
		}
689
		
690
		// move one up
691
		list.swap(slot, slot - 1);
692
		return true;
693
	},
694
	moveSlotDown: function(slot){
695
		var list = this;
696
		
697
		// MODIFIES ARRAY IN PLACE
698
		
699
		// exit quickly if slot not in array, or already at bottom
700
		var al = list.length;
701
		if (slot < 0 || slot >= (al - 1)) {
702
			return false;
703
		}
704
		
705
		// move one down
706
		list.swap(slot, slot + 1);
707
		return true;
708
	},
709
	/** Move an item from the given list, to the start/end of the target list */
710
	moveToArray: function(item, toList, evenIfExists = false, addToEnd = true){
711
		var list = this;
712
		
713
		// remove from source list
714
		RemoveOne(list, item);
715
		
716
		// add to target list
717
		if (evenIfExists || toList.indexOf(item) === -1) {
718
			if (addToEnd) {
719
				toList.push(item);
720
			}else{
721
				toList.unshift(item);
722
			}
723
			return true;
724
		}
725
		
726
		return false;
727
	},
728
729
	
730
	contains: function(value){
731
		var list = this;
732
		if (list.length === 1) {
733
			return list[0] == value;
734
		}
735
		return list.indexOf(value) > -1;
736
	},
737
	containsAny: function(values){
738
		var list = this;
739
		return IndexOfAny(list, values) > -1;
740
	},
741
	containsAll: function(values){
742
		var list = this;
743
		
744
		// exit if either null
745
		if (list == null || values == null || list.length === 0 || values.length === 0) {
746
			return false;
747
		}
748
		
749
		// check if all found
750
		for (var f = 0, fl = values.length;f<fl;f++){
751
			if (list.indexOf(values[f]) === -1) {
752
				return false;
753
			}
754
		}
755
		return true;
756
	},
757
	
758
759
	indexOfArray: function(containsArr){
760
		var list = this;
761
		
762
		// returns index of containing list in main array
763
		
764
		if (list.length < containsArr.length) {
765
			return -1;
766
		}
767
		
768
		var cl = containsArr.length;
769
		for (var a = 0, al = list.length - (cl - 1);a<al;a++){
770
			
771
			var allMatch = true;
772
			for (var c = 0;c<cl;c++){
773
				if (list[a+c] != containsArr[c]) {
774
					allMatch = false;
775
					break;
776
				}
777
			}
778
			
779
			if (allMatch) {
780
				return a;
781
			}
782
		}
783
		return -1;
784
	},
785
786
	
787
	/** Returns the nearest existing slot value in the array. Returns `ifNoSlots` if the array is empty. */
788
	within: function(slot, ifNoSlots = null){
789
		var list = this;
790
		
791
		// return null if array empty
792
		var len = list.length;
793
		if (len === 0) {
794
			return ifNoSlots;
795
		}
796
		
797
		// return first slot if index negative
798
		if (slot < 0) {
799
			return list[0];
800
		}
801
		
802
		// return last slot if index more than last slot
803
		if (slot >= len) {
804
			return list[len - 1];
805
		}
806
		
807
		// return given slot if within array
808
		return list[slot];
809
	},
810
	
811
	first: function(list){
812
		var list = this;
813
		var len = list.length;
814
		if (len === 0) {
815
			return null;
816
		}
817
		return list[0];
818
	},
819
	firstExisting: function(slots, blankVal = null){
820
		var list = this;
821
		for (var s = 0, sl = slots.length;s<sl;s++){
822
			var val;
823
			if ((val = list[slots[s]]) != blankVal) {
824
				return val;
825
			}
826
		}
827
		return null;
828
	},
829
	last: function(list){
830
		var list = this;
831
		var len = list.length;
832
		if (len === 0) {
833
			return null;
834
		}
835
		return list[len-1];
836
	},
837
	lastX: function(count){
838
		var list = this;
839
		var s = (0).max(list.length - count);
840
		return list.slice(s, list.length);
841
	},
842
	setFirst: function(value){
843
		var list = this;
844
		var len = list.length;
845
		if (len === 0) {
846
			return;
847
		}
848
		list[0] = value;
849
	},
850
	setLast: function(value){
851
		var list = this;
852
		var len = list.length;
853
		if (len === 0) {
854
			return;
855
		}
856
		list[len-1] = value;
857
	},
858
	
859
	random: function(list){
860
		var list = this;
861
		
862
		// return null if array empty
863
		if (list.length === 0) {
864
			return null;
865
		}
866
		
867
		// return random slot within array
868
		return list[parseInt(Math.random() * 1000000) % list.length];
869
	},
870
871
	pick: function(IDs, sameSlots = false, fastAndUnsafe = false, out = null, evenIfNull = false){
872
		var list = this;
873
		if (out == null){
874
			out = [];
875
		}
876
		
877
		if (IDs){
878
			if (fastAndUnsafe) {
879
				
880
				for (var i = 0, il = IDs.length;i<il;i++){
881
					var id = IDs[i];
882
					var val = list[id];
883
					if (sameSlots) {
884
						out[id] = val;
885
					}else{
886
						out.push(val);
887
					}
888
				}
889
				
890
			}else{
891
				
892
				for (var i = 0, il = IDs.length;i<il;i++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 880. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable il already seems to be declared on line 880. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
893
					id = IDs[i];
894
					if (id > -1){
895
						val = list[id];
896
						if (val != null || evenIfNull) {
897
							if (sameSlots) {
898
								out[id] = val;
899
							}else{
900
								out.push(val);
901
							}
902
						}
903
					}
904
				}
905
				
906
			}
907
		}
908
		
909
		return out;
910
	},
911
912
	/** Get the data of `list`, by searching `indexID` in `indexArr`, or return `defaultVal` if not found */
913
	getByMatchingArray: function(indexArr, indexID, defaultVal = null){
914
		var list = this;
915
		var slot = indexArr.indexOf(indexID);
916
		return slot === -1 ? defaultVal : list[slot];
917
	},
918
	/** Set the data of `list`, by searching `indexID` in `indexArr` */
919
	setByMatchingArray: function(indexArr, indexID, data){
920
		var list = this;
921
		var slot = indexArr.indexOf(indexID);
922
		if (slot === -1) {
923
			return false;
924
		}
925
		list[slot] = data;
926
		return true;
927
	},
928
	
929
	page: function(page, pageLength, invisibleRows = null){
930
		var list = this;
931
		
932
		// ensure page no. in limits
933
		var lastPage = Math.ceil(list.length / pageLength);
934
		page = page.limitTo(0, lastPage - 1);
935
		
936
		// get first/last row in page
937
		var pageStart = page*pageLength;/// 0-based - first row in page
938
		var pageEnd = (pageStart + pageLength) - 1;/// 0-based - last row in page
939
		
940
		// get on-page rows
941
		var visibleRows = list.part(pageStart, pageLength);
942
		
943
		// get off-page rows
944
		if (invisibleRows) {
945
			invisibleRows.addRange(list, 0, pageStart - 1);
946
			invisibleRows.addRange(list, pageEnd + 1, list.length - 1);
947
		}
948
		
949
		return visibleRows;
950
	},
951
	
952
	trim: function(returnNew = false, trimVal = null){
953
		var list = this;
954
		var first = list.indexOfNot(trimVal);
955
		if (first === -1) {
956
957
			// return new
958
			if (returnNew) {
959
				return [];
960
			}
961
962
			// modify existing
963
			list.length = 0;
964
		}else{
965
966
			// return new
967
			var last = list.lastIndexOfNot(trimVal);
968
			if (returnNew) {
969
				return list.part(first, last);
970
			}
971
972
			// modify existing
973
			if (first != -1 && first != 0){
974
				list.removePart(0, first-1);
975
			}
976
			if (last != -1){
977
				list.length = last - first + 1; 
978
			}
979
		}
980
		return list;
981
	},
982
983
	trimLeft: function(returnNew = false, trimVal = null){
984
		var list = this;
985
		var first = list.indexOfNot(trimVal);
986
		if (first === -1) {
987
988
			// return new
989
			if (returnNew) {
990
				return [];
991
			}
992
993
			// modify existing
994
			list.length = 0;
995
996
		}else{
997
998
			// return new
999
			if (returnNew) {
1000
				return list.afterIndex(first);
1001
			}
1002
1003
			// modify existing
1004
			if (first != -1 && first != 0){
1005
				list.removePart(0, first-1);
1006
			}
1007
		}
1008
		return list;
1009
	},
1010
	trimRight: function(returnNew = false, trimVal = null){
1011
		var list = this;
1012
		var last = list.indexOfNot(trimVal, true);
1013
		if (last === -1) {
1014
1015
			// return new
1016
			if (returnNew) {
1017
				return [];
1018
			}
1019
			
1020
			// modify existing
1021
			list.length = 0;
1022
		}else{
1023
1024
			// return new
1025
			if (returnNew) {
1026
				return list.beforeIndex(last);
1027
			}
1028
1029
			// modify existing
1030
			list.length = last + 1;
1031
		}
1032
		return list;
1033
	},
1034
	
1035
	transpose: function() {
1036
		var arr = this;
1037
		var transposed = [];
1038
		
1039
		for (var r = 0; r < arr.length; r++) {
1040
			for (var c = 0; c < arr[r].length; c++) {
1041
				if (transposed[c] == null) {
1042
					transposed[c] = [];
1043
				}
1044
				transposed[c][r] = arr[r][c];
1045
			}
1046
		}
1047
		
1048
		return transposed;
1049
	},
1050
	
1051
	
1052
	// fast sorting
1053
	quickSort: function(ascending = true){
1054
		var input = this;
1055
		
1056
		var len = input.length;
1057
		if (len >= 2) {
1058
			
1059
			// sort in place
1060
			input._quickSort(0, len - 1, 0);
1061
			
1062
			// flip if descending wanted
1063
			if (!ascending) {
1064
				input.reverse();
1065
			}
1066
			
1067
		}
1068
	},
1069
1070
	indexedQuickSort: function(ascending = true){
1071
		var input = this;
1072
		
1073
		var len = input.length;
1074
		if (len >= 2) {
1075
			
1076
			// indexed sort
1077
			var index = UB.newArray(0, input.length);
1078
			input._indexedQuickSort(index, 0, len - 1, 0);
1079
			
1080
			// flip if descending wanted
1081
			if (!ascending) {
1082
				index.reverse();
1083
			}
1084
			
1085
			return index;
1086
		}
1087
		
1088
		return null;
1089
	},
1090
	
1091
	/** INTERNAL FUNCTION, do not use directly */
1092
	_quickSort: function(left, right, d){
1093
		var input = this;
1094
		if (left >= right){
1095
			return;
1096
		}
1097
		var j = right, i = left;
1098
		var size = right - left;
1099
		//var pivotPoint = input[uint((right>>>1) + (left>>>1))], t;
1100
		var pivotPoint = input[((right>>>1) + (left>>>1)) >>> 0], t;
1101
		do {
1102
			if (size < 9) {
1103
				pivotPoint = input[left];
1104
				do {
1105
					do {
1106
						left++;
1107
						if (input[left] < pivotPoint) {
1108
							pivotPoint = input[left];
1109
							do { // this section can be improved.
1110
								input[left--] = input[left];
1111
							} while (left > i && pivotPoint < input[left]);
1112
							input[left] = pivotPoint;
1113
						}
1114
					} while (left < right);
1115
					i++;
1116
					left = i;
1117
					pivotPoint = input[left];
1118
				} while (i < right);
1119
				return;
1120
			}
1121
			while (left < right) {
1122
				if (input[right] > pivotPoint){
1123
					do { right--; }
1124
					while (input[right] > pivotPoint);
1125
				}
1126
				if (input[left] < pivotPoint){
1127
					do { left++; }
1128
					while (input[left] < pivotPoint);
1129
				}
1130
				if (left < right) {
1131
					t = input[left];
1132
					input[left] = input[right];
1133
					input[right] = t;
1134
					left++;
1135
					right--;
1136
				}
1137
			}
1138
			if (right) {
1139
				if (left === right) {
1140
					if (input[left] < pivotPoint){
1141
						left++;
1142
					}else if (input[right] > pivotPoint){
1143
						right--;
1144
					}
1145
				}
1146
				if (i < right) {
1147
					input._quickSort(i, right, d + 1);
1148
				}
1149
			}
1150
			left |= int(!left) & int(!right);
1151
			if (j <= left){
1152
				return;
1153
			}
1154
			i = left;
1155
			right = j;
1156
			//pivotPoint = input[uint((right >>> 1) + (left >>> 1))];
1157
			pivotPoint = input[((right >>> 1) + (left >>> 1)) >>> 0];
1158
			size = right - left;
1159
			d++;
1160
		} while (true);
1161
	},
1162
1163
	/** INTERNAL FUNCTION, do not use directly */
1164
	_indexedQuickSort: function(indexed, left, right, d){
1165
		var input = this;
1166
		if (left >= right){
1167
			return;
1168
		}
1169
		
1170
		// status
1171
		var j;
1172
		var i;
1173
		var size = (j = right) - (i = left);
1174
		//var pivotPoint = (input[uint((right>>>1) + (left>>>1))]);
1175
		var pivotPoint = (input[((right>>>1) + (left>>>1)) >>> 0]);
1176
		
1177
		// temps
1178
		var pivotIndex;
1179
		var temp;
1180
		var temp2;
1181
		
1182
		do {
1183
			
1184
			//{ part 1
1185
			if (size < 9) {
1186
				pivotPoint = input[left];
1187
				do {
1188
					do {
1189
						left++;
1190
						temp = input[left];
1191
						if (temp < pivotPoint) {
1192
							
1193
							pivotIndex = indexed[left];
1194
							pivotPoint = temp;
1195
							
1196
							do {
1197
								
1198
								// change vals
1199
								input[left] = input[left - 1];
1200
								
1201
								// change indices
1202
								indexed[left] = indexed[left - 1];
1203
								
1204
								left--;
1205
								
1206
							} while (left > i && pivotPoint < input[left]);
1207
							
1208
							// change vals
1209
							input[left] = pivotPoint;
1210
							
1211
							// change indices
1212
							indexed[left] = pivotIndex;
1213
						}
1214
					} while (left < right);
1215
					i++;
1216
					pivotPoint = input[left = i];
1217
				} while (i < right);
1218
				return;
1219
			}
1220
			//}
1221
			
1222
			//{ part 2
1223
			while (left < right) {
1224
				if (input[right] > pivotPoint) {
1225
					do {
1226
						right--;
1227
					} while (input[right] > pivotPoint);
1228
				}
1229
				if (input[left] < pivotPoint) {
1230
					do {
1231
						left++;
1232
					} while (input[left] < pivotPoint);
1233
				}
1234
				if (left < right) {
1235
					
1236
					// flip values
1237
					temp = input[left];
1238
					input[left] = input[right];
1239
					input[right] = temp;
1240
					
1241
					// flip indices
1242
					temp2 = indexed[left];
1243
					indexed[left] = indexed[right];
1244
					indexed[right] = temp2;
1245
					
1246
					left++;
1247
					right--;
1248
				}
1249
			}
1250
			//}
1251
			
1252
			//{ part 2
1253
			if (right) {
1254
				if (left === right) {
1255
					if (input[left] < pivotPoint) {
1256
						left++;
1257
					}else if (input[right] > pivotPoint) {
1258
						right--;
1259
					}
1260
				}
1261
				if (i < right) {
1262
					
1263
					// recurse
1264
					input._indexedQuickSort(indexed, i, right, d + 1);
1265
					
1266
				}
1267
			}
1268
			//}
1269
			
1270
			left |= int(!left) & int(!right);
1271
			if (j <= left) {
1272
				return;
1273
			}
1274
			i = left;
1275
			right = j;
1276
			//pivotPoint = input[uint((right >>> 1) + (left >>> 1))];
1277
			pivotPoint = input[((right >>> 1) + (left >>> 1)) >>> 0];
1278
			size = right - left;
1279
			d++;
1280
		} while (true);
1281
	},
1282
	
1283
	
1284
	next: function(obj, wrap = false){
1285
		var list = this;
1286
		if (list == null) {
1287
			return null;
1288
		}
1289
		var i = list.indexOf(obj);
1290
		if (i > -1) {
1291
			return (wrap && i >= (list.length - 1)) ? list[0] : list[i + 1];
1292
		}
1293
		return null;
1294
	},
1295
	prev: function(obj, wrap = false){
1296
		var list = this;
1297
		if (list == null) {
1298
			return null;
1299
		}
1300
		var i = list.indexOf(obj);
1301
		if (i > 0) {
1302
			return wrap ? list[list.length - 1] : list[i - 1];
1303
		}
1304
		return null;
1305
	},
1306
	
1307
	
1308
	
1309
	none:null
1310
};
1311
1312
// register funcs
1313
UB.registerFuncs(Array.prototype, arrayFuncs);
1314