Total Complexity | 245 |
Complexity/F | 3.45 |
Lines of Code | 1058 |
Function Count | 71 |
Duplicated Lines | 28 |
Ratio | 2.65 % |
Changes | 2 | ||
Bugs | 0 | Features | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like src/ub.arrays.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | /** global: UB */ |
||
5 | var arrayFuncs = { |
||
6 | |||
7 | indexOf: function(value){ |
||
8 | var list = this; |
||
9 | if (list.length === 0) { |
||
10 | return -1; |
||
11 | } |
||
12 | for (var a = 0, al = list.length;a<al;a++){ |
||
13 | if (list[a] == value){ |
||
14 | return a; |
||
15 | } |
||
16 | } |
||
17 | return -1; |
||
18 | }, |
||
19 | View Code Duplication | lastIndexOf: function(value){ |
|
|
|||
20 | var list = this; |
||
21 | if (list.length === 0) { |
||
22 | return -1; |
||
23 | } |
||
24 | for (var a = list.length-1;a>=0;a--){ |
||
25 | if (list[a] == value){ |
||
26 | return a; |
||
27 | } |
||
28 | } |
||
29 | return -1; |
||
30 | }, |
||
31 | isEqual: function(list2){ |
||
32 | var list = this; |
||
33 | if (list == null || list2 == null) { |
||
2 ignored issues
–
show
|
|||
34 | return list == list2; |
||
35 | } |
||
36 | if(list.length != list2.length){ |
||
37 | return false; |
||
38 | } |
||
39 | |||
40 | var len = list.length; |
||
41 | |||
42 | for (var i = 0;i<len;i++){ |
||
43 | if(list[i] !== list2[i]){ |
||
44 | return false; |
||
45 | } |
||
46 | } |
||
47 | |||
48 | return true; |
||
49 | }, |
||
50 | isNotEqual: function(list2){ |
||
51 | var list = this; |
||
52 | return !IsEqual(list, list2); |
||
53 | }, |
||
54 | |||
55 | exists: function(){ |
||
56 | var list = this; |
||
57 | return list != null && list.length > 0; |
||
1 ignored issue
–
show
|
|||
58 | }, |
||
59 | isFirst: function(value){ |
||
60 | var list = this; |
||
61 | return list != null && list[0] == value; |
||
1 ignored issue
–
show
|
|||
62 | }, |
||
63 | isLast: function(value){ |
||
64 | var list = this; |
||
65 | return list != null && list[list.length - 1] == value; |
||
1 ignored issue
–
show
|
|||
66 | }, |
||
67 | View Code Duplication | count: function(value, not = false){ |
|
68 | var list = this; |
||
69 | var total = 0; |
||
70 | for (var a = 0, al = list.length;a<al;a++){ |
||
71 | if (not) { |
||
72 | if (list[a] != value) { |
||
73 | total++; |
||
74 | } |
||
75 | }else { |
||
76 | if (list[a] == value) { |
||
77 | total++; |
||
78 | } |
||
79 | } |
||
80 | } |
||
81 | return total; |
||
82 | }, |
||
83 | or: function(list2){ |
||
84 | var list = this; |
||
85 | if (Exists(list)) { |
||
86 | return list; |
||
87 | } |
||
88 | return list2; |
||
89 | }, |
||
90 | |||
91 | part: function(start, end){ |
||
92 | var list = this; |
||
93 | |||
94 | // quickly exit if no items or no results possible |
||
95 | if (list == null || list.length === 0 || start > end || start >= list.length) { |
||
1 ignored issue
–
show
|
|||
96 | return []; |
||
97 | } |
||
98 | |||
99 | // just get the part we need |
||
100 | return list.slice(start, end + 1); |
||
101 | }, |
||
102 | |||
103 | swap: function(slot1, slot2){ |
||
104 | var list = this; |
||
105 | var temp = list[slot2]; |
||
106 | list[slot2] = list[slot1]; |
||
107 | list[slot1] = temp; |
||
108 | }, |
||
109 | |||
110 | add: function(item){ |
||
111 | var list = this; |
||
112 | list.push(item); |
||
113 | return list.length - 1; |
||
114 | }, |
||
115 | addToStart: function(item){ |
||
116 | var list = this; |
||
117 | list.unshift(item); |
||
118 | return 0; |
||
119 | }, |
||
120 | /** return false if item exists, true if item does not */ |
||
121 | addOnce: function(value){ |
||
122 | var list = this; |
||
123 | |||
124 | // return false if item exists |
||
125 | if (list.indexOf(value) > -1) { |
||
126 | return false; |
||
127 | } |
||
128 | |||
129 | // add if not found |
||
130 | list.push(value); |
||
131 | return true; |
||
132 | }, |
||
133 | |||
134 | addArray: function(toAdd, addAtSlot = -1, modifyMain = true){ |
||
135 | var list = this; |
||
136 | |||
137 | if (toAdd != null && toAdd.length > 0) { |
||
1 ignored issue
–
show
|
|||
138 | if (!modifyMain) { |
||
139 | list = list.concat(); /// shallow clone |
||
140 | } |
||
141 | |||
142 | // set length first so allocates memory (maybe?) |
||
143 | var origLen = list.length; |
||
144 | if (addAtSlot == -1){ |
||
145 | list.length += toAdd.length; |
||
146 | } |
||
147 | |||
148 | // set all slots |
||
149 | var next = addAtSlot == -1 ? origLen : addAtSlot; |
||
150 | for (var a = 0, al = toAdd.length;a<al;a++, next++){ |
||
151 | list[next] = toAdd[a]; |
||
152 | } |
||
153 | } |
||
154 | return list; |
||
155 | }, |
||
156 | |||
157 | /** adds the given value many times */ |
||
158 | addManyTimes: function(val, times){ |
||
159 | var list = this; |
||
160 | |||
161 | if (times <= 0) { |
||
162 | return list; |
||
163 | } |
||
164 | |||
165 | var n = list.length; |
||
166 | for (var t = 0;t<times;t++){ |
||
167 | list[n++] = val; |
||
168 | } |
||
169 | |||
170 | return list; |
||
171 | }, |
||
172 | |||
173 | addRange: function(toAdd, startSlot, endSlot){ |
||
174 | var list = this; |
||
175 | |||
176 | // exit if no work |
||
177 | if (endSlot < startSlot) { |
||
178 | return; |
||
179 | } |
||
180 | |||
181 | // per wanted slot of the `add` array |
||
182 | startSlot = startSlot.limitToArray(toAdd); |
||
183 | endSlot = endSlot.limitToArray(toAdd); |
||
184 | for (var s = startSlot;s <= endSlot;s++){ |
||
185 | |||
186 | // add into `main` array |
||
187 | list.push(toAdd[s]); |
||
188 | |||
189 | } |
||
190 | }, |
||
191 | |||
192 | /** returns final index of added item, or index of already existing item */ |
||
193 | findOrAdd: function(value){ |
||
194 | var list = this; |
||
195 | |||
196 | // return index of item if exists |
||
197 | var i = list.indexOf(value); |
||
198 | if (i > -1) { |
||
199 | return i; |
||
200 | } |
||
201 | |||
202 | // add if not found |
||
203 | i = list.length; |
||
204 | list[i] = value; |
||
205 | return i; |
||
206 | }, |
||
207 | |||
208 | insertOne: function(item, slot){ |
||
209 | var list = this; |
||
210 | |||
211 | // adds one slot at the given point |
||
212 | // modifies the main array |
||
213 | |||
214 | list.splice(slot, 0, item); |
||
215 | }, |
||
216 | |||
217 | /** if slot = -1 or outside the array, the item is added to the END of the array. |
||
218 | * Otherwise the item is added at the given slot. */ |
||
219 | insertOneOrAdd: function(item, slot){ |
||
220 | var list = this; |
||
221 | |||
222 | // adds one slot at the given point |
||
223 | // modifies the main array |
||
224 | |||
225 | if (slot < 0 || slot >= list.length) { |
||
226 | list.push(item); |
||
227 | return list.length - 1; |
||
228 | }else { |
||
229 | list.splice(slot, 0, item); |
||
230 | return slot; |
||
231 | } |
||
232 | }, |
||
233 | insertArray: function(newItems, slot, returnNew = true){ |
||
234 | var list = this; |
||
235 | |||
236 | // adds many slots at the given point |
||
237 | // returns a new array |
||
238 | if(returnNew){ |
||
239 | return list.slice(0, slot).concat(newItems).concat(list.slice(slot)); |
||
240 | } |
||
241 | |||
242 | // adds many slots at the given point |
||
243 | // modifies the main array |
||
244 | for (var a = 0, al = newItems.length;a<al;a++){ |
||
245 | list.splice(slot++, 0, newItems[a]); |
||
246 | } |
||
247 | return list; |
||
248 | }, |
||
249 | insertArrayAfter: function(newItems, after){ |
||
250 | var list = this; |
||
251 | if (list.isLast(after)) { |
||
252 | list.addArray(newItems); |
||
253 | } else { |
||
254 | var i = list.indexOf(after); |
||
255 | list.insertArray(i + 1, newItems); |
||
256 | } |
||
257 | }, |
||
258 | |||
259 | |||
260 | removeAndInsert: function(from, to){ |
||
261 | var list = this; |
||
262 | |||
263 | // ensure slots within array |
||
264 | var al = list.length; |
||
265 | from = from.limitTo(0, al - 1); |
||
266 | to = to.limitTo(0, al - 1); |
||
267 | if (to < from) { |
||
268 | var i1 = to; |
||
269 | var i2 = from; |
||
270 | }else { |
||
271 | var i1 = from; |
||
272 | var i2 = to; |
||
273 | } |
||
274 | |||
275 | // fill unaffected header |
||
276 | var result = []; |
||
277 | if(i1 > 0){ |
||
278 | for (var a = 0;a<i1;a++){ |
||
279 | result[a] = list[a]; |
||
280 | } |
||
281 | } |
||
282 | |||
283 | // fill "to" |
||
284 | result[to] = list[from]; |
||
285 | |||
286 | // fill between from and to |
||
287 | if(to < from){ |
||
288 | for (a = to + 1; a <= from; a++) { |
||
289 | result[a] = list[a - 1]; |
||
290 | } |
||
291 | }else { |
||
292 | for (a = from; a < to; a++) { |
||
293 | result[a] = list[a + 1]; |
||
294 | } |
||
295 | } |
||
296 | |||
297 | // fill unaffected footer |
||
298 | for (var a = i2 + 1;a<al;a++){ |
||
299 | result[a] = list[a]; |
||
300 | } |
||
301 | |||
302 | return result; |
||
303 | }, |
||
304 | |||
305 | /** replace a range of items with a given array */ |
||
306 | replaceRange: function(replaceStartSlot, replaceEndSlot, newItems, returnNew = true){ |
||
307 | var list = this; |
||
308 | |||
309 | |||
310 | // simply remove a single item |
||
311 | if (replaceStartSlot == replaceEndSlot && newItems.length === 0) { |
||
312 | if (returnNew) { |
||
313 | list = list.concat(); |
||
314 | } |
||
315 | list.splice(replaceStartSlot, 1); |
||
316 | return list; |
||
317 | |||
318 | // simply replace a single item |
||
319 | }else if (replaceStartSlot == replaceEndSlot && newItems.length == 1) { |
||
1 ignored issue
–
show
|
|||
320 | if (returnNew) { |
||
321 | list = list.concat(); |
||
322 | } |
||
323 | list[replaceStartSlot] = newItems[0]; |
||
324 | return list; |
||
325 | |||
326 | }else{ |
||
327 | |||
328 | // alt method if returning a new array |
||
329 | if(returnNew){ |
||
330 | return list.slice(0, replaceStartSlot).concat(newItems).concat(list.slice(replaceEndSlot + 1)); |
||
331 | } |
||
332 | |||
333 | // remove many |
||
334 | list.splice(replaceStartSlot, (replaceEndSlot - replaceStartSlot) + 1); |
||
335 | |||
336 | // insert many |
||
337 | var slot = replaceStartSlot; |
||
338 | for (var a = 0, al = newItems.length;a<al;a++){ |
||
339 | list.splice(slot++, 0, newItems[a]); |
||
340 | } |
||
341 | } |
||
342 | return list; |
||
343 | }, |
||
344 | |||
345 | replace: function(find, replace, stringReplace = false){ |
||
346 | var list = this; |
||
347 | for (var i = 0, il = list.length;i<il;i++){ |
||
348 | if (stringReplace){ |
||
349 | |||
350 | // replace substring within string items |
||
351 | var str = list[i]; |
||
352 | if (str && str.constructor === String) { |
||
353 | list[i] = str.replaceAll(find, replace); |
||
354 | } |
||
355 | }else{ |
||
356 | |||
357 | // replace entire items |
||
358 | if (list[i] == find) { |
||
359 | list[i] = replace; |
||
360 | } |
||
361 | } |
||
362 | } |
||
363 | }, |
||
364 | replaceOnce: function(find, replace){ |
||
365 | var list = this; |
||
366 | for (var i = 0, il = list.length;i<il;i++){ |
||
367 | if (list[i] == find) { |
||
368 | list[i] = replace; |
||
369 | return; |
||
370 | } |
||
371 | } |
||
372 | }, |
||
373 | replaceMany: function(findArray, replaceArray){ |
||
374 | var list = this; |
||
375 | if (findArray.length != replaceArray.length){ |
||
376 | return; |
||
377 | } |
||
378 | for (var i = 0, il = list.length;i<il;i++){ |
||
379 | for (var f = 0, fl = findArray.length;f<fl;f++){ |
||
380 | var find = findArray[f]; |
||
381 | if (list[i] == find) { |
||
382 | list[i] = replaceArray[f]; |
||
383 | break; |
||
384 | } |
||
385 | } |
||
386 | } |
||
387 | }, |
||
388 | |||
389 | |||
390 | remove: function(value, stringReplace = false){ |
||
391 | var list = this; |
||
392 | for (var i = 0, il = list.length;i<il;i++){ |
||
393 | if (stringReplace){ |
||
394 | |||
395 | // remove substring within string items |
||
396 | var str = list[i]; |
||
397 | if (str && str.constructor === String) { |
||
398 | list[i] = str.removeAll(find); |
||
399 | } |
||
400 | }else{ |
||
401 | |||
402 | // remove entire items |
||
403 | if (list[i] == value) { |
||
404 | list.splice(i, 1); |
||
405 | i--; |
||
1 ignored issue
–
show
|
|||
406 | il--; |
||
407 | } |
||
408 | } |
||
409 | } |
||
410 | }, |
||
411 | removeOnce: function(val){ |
||
412 | var list = this; |
||
413 | var i = list.indexOf(val); |
||
414 | if (i > -1) { |
||
415 | list.splice(i, 1); |
||
416 | } |
||
417 | return i; |
||
418 | }, |
||
419 | removeFirst: function(returnNew = false){ |
||
420 | var list = this; |
||
421 | if (returnNew) { |
||
422 | return list.slice(1); |
||
423 | }else{ |
||
424 | if (list.length > 0) { |
||
425 | list.splice(0, 1); |
||
426 | } |
||
427 | return list; |
||
428 | } |
||
429 | }, |
||
430 | removeFirstX: function(count, returnNew = false){ |
||
431 | var list = this; |
||
432 | |||
433 | // if fewer items than wanted, clear entire array |
||
434 | if (list.length < count) { |
||
435 | if (returnNew) { |
||
436 | return []; |
||
437 | } |
||
438 | list.length = 0; |
||
439 | return list; |
||
440 | } |
||
441 | |||
442 | // delete X items from start |
||
443 | if (returnNew) { |
||
444 | return list.slice(count); |
||
445 | }else{ |
||
446 | list.splice(0, count); |
||
447 | return list; |
||
448 | } |
||
449 | }, |
||
450 | removeLast: function(returnNew = false){ |
||
451 | var list = this; |
||
452 | if (returnNew) { |
||
453 | return list.slice(0, list.length - 1); |
||
454 | } |
||
455 | if (list.length > 0) { |
||
456 | list.splice( - 1, 1); |
||
457 | } |
||
458 | return list; |
||
459 | }, |
||
460 | removeLastX: function(count, returnNew = false){ |
||
461 | var list = this; |
||
462 | |||
463 | // if fewer items than wanted, clear entire array |
||
464 | if (list.length < count) { |
||
465 | if (returnNew) { |
||
466 | return []; |
||
467 | } |
||
468 | list.length = 0; |
||
469 | return list; |
||
470 | } |
||
471 | |||
472 | // delete X items from end |
||
473 | if (returnNew) { |
||
474 | return list.slice(0, list.length - count); |
||
475 | }else{ |
||
476 | list.splice( -count, count); |
||
477 | return list; |
||
478 | } |
||
479 | }, |
||
480 | |||
481 | removeEdges: function(fromLeftEdge, fromRightEdge){ |
||
482 | var list = this; |
||
483 | if ((list.length - fromLeftEdge - fromRightEdge) <= 0) { |
||
484 | return []; |
||
485 | } |
||
486 | return list.slice(fromLeftEdge, list.length - fromRightEdge); |
||
487 | }, |
||
488 | |||
489 | contains: function(value){ |
||
490 | var list = this; |
||
491 | if (list.length == 1) { |
||
1 ignored issue
–
show
|
|||
492 | return list[0] == value; |
||
493 | } |
||
494 | return list.indexOf(value) > -1; |
||
495 | }, |
||
496 | containsAny: function(values){ |
||
497 | var list = this; |
||
498 | return IndexOfAny(list, values) > -1; |
||
499 | }, |
||
500 | containsAll: function(values){ |
||
501 | var list = this; |
||
502 | |||
503 | // exit if either null |
||
504 | if (list == null || values == null || list.length === 0 || values.length === 0) { |
||
2 ignored issues
–
show
|
|||
505 | return false; |
||
506 | } |
||
507 | |||
508 | // check if all found |
||
509 | for (var f = 0, fl = values.length;f<fl;f++){ |
||
510 | if (list.indexOf(values[f]) == -1) { |
||
511 | return false; |
||
512 | } |
||
513 | } |
||
514 | return true; |
||
515 | }, |
||
516 | |||
517 | |||
518 | splitAt: function(slot, includeSlot = false, includeInFirst = false){ |
||
519 | var list = this; |
||
520 | if (includeSlot) { |
||
521 | if (includeInFirst) { |
||
522 | return [list.slice(0, slot + 1), list.slice(slot + 1)]; |
||
523 | }else { |
||
524 | return [list.slice(0, slot), list.slice(slot)]; |
||
525 | } |
||
526 | } |
||
527 | return [list.slice(0, slot), list.slice(slot+1)]; |
||
528 | }, |
||
529 | splitAtEvery: function(val){ |
||
530 | var list = this; |
||
531 | var splits = []; |
||
532 | var lastSlot = 0; |
||
533 | for (var a = 0, al = list.length;a<al;a++){ |
||
534 | if (list[a] == val && a > lastSlot) { |
||
535 | splits.push(list.slice(lastSlot, a)); |
||
536 | lastSlot = a + 1; |
||
537 | } |
||
538 | } |
||
539 | return splits; |
||
540 | }, |
||
541 | |||
542 | moveToTop: function(slot, returnNew = false){ |
||
543 | var list = this; |
||
544 | |||
545 | if (returnNew){ |
||
546 | |||
547 | // ALWAYS RETURNS NEW ARRAY |
||
548 | |||
549 | // exit quickly if slot not in array |
||
550 | var al = list.length; |
||
551 | if (slot < 0 || slot >= al) { |
||
552 | return list.concat(); |
||
553 | } |
||
554 | |||
555 | // create new array with slot on top |
||
556 | var newArr = [list[slot]]; |
||
557 | var n = 1; |
||
558 | |||
559 | // add all other slots |
||
560 | for (var a = 0;a<al;a++){ |
||
561 | if (a != slot) { |
||
562 | newArr[n++] = list[a]; |
||
563 | } |
||
564 | } |
||
565 | |||
566 | return newArr; |
||
567 | |||
568 | }else{ |
||
569 | |||
570 | // MODIFIES ARRAY IN PLACE |
||
571 | |||
572 | // exit quickly if slot not in array |
||
573 | var al = list.length; |
||
574 | if (slot < 0 || slot >= al) { |
||
575 | return; |
||
576 | } |
||
577 | |||
578 | // delete and re-add slot |
||
579 | var val = list[slot]; |
||
580 | list.splice(slot, 1); |
||
581 | list.unshift(val); |
||
582 | } |
||
583 | }, |
||
584 | moveToBottom: function(slot, returnNew = false){ |
||
585 | var list = this; |
||
586 | |||
587 | if (returnNew){ |
||
588 | |||
589 | // ALWAYS RETURNS NEW ARRAY |
||
590 | |||
591 | // exit quickly if slot not in array |
||
592 | var al = list.length; |
||
593 | if (slot < 0 || slot >= al) { |
||
594 | return list.concat(); |
||
595 | } |
||
596 | |||
597 | // create new array with slot on top |
||
598 | var newArr = []; |
||
599 | var n = 0; |
||
600 | |||
601 | // add all other slots |
||
602 | for (var a = 0;a<al;a++){ |
||
603 | if (a != slot) { |
||
604 | newArr[n++] = list[a]; |
||
605 | } |
||
606 | } |
||
607 | |||
608 | // add slot to bottom |
||
609 | newArr[n++] = list[slot]; |
||
610 | return newArr; |
||
611 | |||
612 | }else{ |
||
613 | |||
614 | // MODIFIES ARRAY IN PLACE |
||
615 | |||
616 | // exit quickly if slot not in array |
||
617 | var al = list.length; |
||
618 | if (slot < 0 || slot >= al) { |
||
619 | return; |
||
620 | } |
||
621 | |||
622 | // delete and re-add slot |
||
623 | var val = list[slot]; |
||
624 | list.splice(slot, 1); |
||
625 | list.push(val); |
||
626 | } |
||
627 | }, |
||
628 | moveUp: function(item){ |
||
629 | var list = this; |
||
630 | |||
631 | // MODIFIES ARRAY IN PLACE |
||
632 | |||
633 | // exit quickly if slot not in array, or already on top |
||
634 | var slot = list.indexOf(item); |
||
635 | if (slot <= 0) { |
||
636 | return false; |
||
637 | } |
||
638 | |||
639 | // move one up |
||
640 | Swap(list, slot, slot - 1); |
||
641 | return true; |
||
642 | }, |
||
643 | moveDown: function(item){ |
||
644 | var list = this; |
||
645 | |||
646 | // MODIFIES ARRAY IN PLACE |
||
647 | |||
648 | // exit quickly if slot not in array, or already at bottom |
||
649 | var al = list.length; |
||
650 | var slot = list.indexOf(item); |
||
651 | if (slot < 0 || slot >= (al - 1)) { |
||
652 | return false; |
||
653 | } |
||
654 | |||
655 | // move one down |
||
656 | Swap(list, slot, slot + 1); |
||
657 | return true; |
||
658 | }, |
||
659 | moveSlotUp: function(slot){ |
||
660 | var list = this; |
||
661 | |||
662 | // MODIFIES ARRAY IN PLACE |
||
663 | |||
664 | // exit quickly if slot not in array, or already on top |
||
665 | var al = list.length; |
||
666 | if (slot <= 0 || slot >= al) { |
||
667 | return false; |
||
668 | } |
||
669 | |||
670 | // move one up |
||
671 | Swap(list, slot, slot - 1); |
||
672 | return true; |
||
673 | }, |
||
674 | moveSlotDown: function(slot){ |
||
675 | var list = this; |
||
676 | |||
677 | // MODIFIES ARRAY IN PLACE |
||
678 | |||
679 | // exit quickly if slot not in array, or already at bottom |
||
680 | var al = list.length; |
||
681 | if (slot < 0 || slot >= (al - 1)) { |
||
682 | return false; |
||
683 | } |
||
684 | |||
685 | // move one down |
||
686 | Swap(list, slot, slot + 1); |
||
687 | return true; |
||
688 | }, |
||
689 | /** Move an item from the given list, to the start/end of the target list */ |
||
690 | moveToArray: function(item, toList, evenIfExists = false, addToEnd = true){ |
||
691 | var list = this; |
||
692 | |||
693 | // remove from source list |
||
694 | RemoveOne(list, item); |
||
695 | |||
696 | // add to target list |
||
697 | if (evenIfExists || toList.indexOf(item) == -1) { |
||
698 | if (addToEnd) { |
||
699 | toList.push(item); |
||
700 | }else{ |
||
701 | toList.unshift(item); |
||
702 | } |
||
703 | return true; |
||
704 | } |
||
705 | |||
706 | return false; |
||
707 | }, |
||
708 | beginsWithArray: function(value){ |
||
709 | return this.startsWithArray(value); |
||
710 | }, |
||
711 | startsWithArray: function(check){ |
||
712 | var list = this; |
||
713 | |||
714 | // quickly test if length sufficient |
||
715 | var clen = check.length; |
||
716 | var mlen = list.length; |
||
717 | if (mlen < clen) { |
||
718 | return false; |
||
719 | } |
||
720 | |||
721 | // check if first slots match |
||
722 | for (var b = 0;b<clen;b++){ |
||
723 | if (list[b] != check[b]) { |
||
724 | return false; |
||
725 | } |
||
726 | } |
||
727 | return true; |
||
728 | }, |
||
729 | endsWithArray: function(check){ |
||
730 | var list = this; |
||
731 | |||
732 | // quickly test if length sufficient |
||
733 | var clen = check.length; |
||
734 | var mlen = list.length; |
||
735 | if (mlen < clen) { |
||
736 | return false; |
||
737 | } |
||
738 | |||
739 | // check if last slots match |
||
740 | var off = (mlen - clen); |
||
741 | for (var b = 0;b<clen;b++){ |
||
742 | if (list[off + b] != check[b]) { |
||
743 | return false; |
||
744 | } |
||
745 | } |
||
746 | return true; |
||
747 | }, |
||
748 | indexOfArray: function(containsArr){ |
||
749 | var list = this; |
||
750 | |||
751 | // returns index of containing list in main array |
||
752 | |||
753 | if (list.length < containsArr.length) { |
||
754 | return -1; |
||
755 | } |
||
756 | |||
757 | var cl = containsArr.length; |
||
758 | for (var a = 0, al = list.length - (cl - 1);a<al;a++){ |
||
759 | |||
760 | var allMatch = true; |
||
761 | for (var c = 0;c<cl;c++){ |
||
762 | if (list[a+c] != containsArr[c]) { |
||
763 | allMatch = false; |
||
764 | break; |
||
765 | } |
||
766 | } |
||
767 | |||
768 | if (allMatch) { |
||
769 | return a; |
||
770 | } |
||
771 | } |
||
772 | return -1; |
||
773 | }, |
||
774 | |||
775 | beginsWith: function(value){ |
||
776 | return this.startsWith(value); |
||
777 | }, |
||
778 | startsWith: function(value){ |
||
779 | var list = this; |
||
780 | return list[0] == value; |
||
781 | }, |
||
782 | endsWith: function(value){ |
||
783 | var list = this; |
||
784 | return list[list.length - 1] == value; |
||
785 | }, |
||
786 | |||
787 | next: function(obj, wrap = false){ |
||
788 | var list = this; |
||
789 | if (list == null) { |
||
1 ignored issue
–
show
|
|||
790 | return null; |
||
791 | } |
||
792 | var i = list.indexOf(obj); |
||
793 | if (i > -1) { |
||
794 | return (wrap && i >= (list.length - 1)) ? list[0] : list[i + 1]; |
||
795 | } |
||
796 | return null; |
||
797 | }, |
||
798 | prev: function(obj, wrap = false){ |
||
799 | var list = this; |
||
800 | if (list == null) { |
||
1 ignored issue
–
show
|
|||
801 | return null; |
||
802 | } |
||
803 | var i = list.indexOf(obj); |
||
804 | if (i > 0) { |
||
805 | return wrap ? list[list.length - 1] : list[i - 1]; |
||
806 | } |
||
807 | return null; |
||
808 | }, |
||
809 | |||
810 | |||
811 | /** Returns the nearest existing slot value in the array. Returns `ifNoSlots` if the array is empty. */ |
||
812 | within: function(slot, ifNoSlots = null){ |
||
813 | var list = this; |
||
814 | |||
815 | // return null if array empty |
||
816 | var len = list.length; |
||
817 | if (len == 0) { |
||
1 ignored issue
–
show
|
|||
818 | return ifNoSlots; |
||
819 | } |
||
820 | |||
821 | // return first slot if index negative |
||
822 | if (slot < 0) { |
||
823 | return list[0]; |
||
824 | } |
||
825 | |||
826 | // return last slot if index more than last slot |
||
827 | if (slot >= len) { |
||
828 | return list[len - 1]; |
||
829 | } |
||
830 | |||
831 | // return given slot if within array |
||
832 | return list[slot]; |
||
833 | }, |
||
834 | |||
835 | first: function(list){ |
||
836 | var list = this; |
||
837 | var len = list.length; |
||
838 | if (len == 0) { |
||
1 ignored issue
–
show
|
|||
839 | return null; |
||
840 | } |
||
841 | return list[0]; |
||
842 | }, |
||
843 | firstExisting: function(slots, blankVal = null){ |
||
844 | var list = this; |
||
845 | for (var s = 0, sl = slots.length;s<sl;s++){ |
||
846 | var val; |
||
847 | if ((val = list[slots[s]]) != blankVal) { |
||
848 | return val; |
||
849 | } |
||
850 | } |
||
851 | return null; |
||
852 | }, |
||
853 | last: function(list){ |
||
854 | var list = this; |
||
855 | var len = list.length; |
||
856 | if (len == 0) { |
||
1 ignored issue
–
show
|
|||
857 | return null; |
||
858 | } |
||
859 | return list[len-1]; |
||
860 | }, |
||
861 | lastX: function(count){ |
||
862 | var list = this; |
||
863 | var s = (0).max(list.length - count); |
||
864 | return list.slice(s, list.length); |
||
865 | }, |
||
866 | setFirst: function(value){ |
||
867 | var list = this; |
||
868 | var len = list.length; |
||
869 | if (len == 0) { |
||
1 ignored issue
–
show
|
|||
870 | return; |
||
871 | } |
||
872 | list[0] = value; |
||
873 | }, |
||
874 | setLast: function(value){ |
||
875 | var list = this; |
||
876 | var len = list.length; |
||
877 | if (len == 0) { |
||
1 ignored issue
–
show
|
|||
878 | return; |
||
879 | } |
||
880 | list[len-1] = value; |
||
881 | }, |
||
882 | |||
883 | random: function(list){ |
||
884 | var list = this; |
||
885 | |||
886 | // return null if array empty |
||
887 | if (list.length === 0) { |
||
888 | return null; |
||
889 | } |
||
890 | |||
891 | // return random slot within array |
||
892 | return list[parseInt(Math.random() * 1000000) % list.length]; |
||
893 | }, |
||
894 | |||
895 | pick: function(IDs, sameSlots = false, fastAndUnsafe = false, out = null, evenIfNull = false){ |
||
896 | var list = this; |
||
897 | if (out == null){ |
||
1 ignored issue
–
show
|
|||
898 | out = []; |
||
899 | } |
||
900 | |||
901 | if (IDs){ |
||
902 | if (fastAndUnsafe) { |
||
903 | |||
904 | for (var i = 0, il = IDs.length;i<il;i++){ |
||
905 | var id = IDs[i]; |
||
906 | var val = list[id]; |
||
907 | if (sameSlots) { |
||
908 | out[id] = val; |
||
909 | }else{ |
||
910 | out.push(val); |
||
911 | } |
||
912 | } |
||
913 | |||
914 | }else{ |
||
915 | |||
916 | for (var i = 0, il = IDs.length;i<il;i++){ |
||
917 | id = IDs[i]; |
||
918 | if (id > -1){ |
||
919 | val = list[id]; |
||
920 | if (val != null || evenIfNull) { |
||
1 ignored issue
–
show
|
|||
921 | if (sameSlots) { |
||
922 | out[id] = val; |
||
923 | }else{ |
||
924 | out.push(val); |
||
925 | } |
||
926 | } |
||
927 | } |
||
928 | } |
||
929 | |||
930 | } |
||
931 | } |
||
932 | |||
933 | return out; |
||
934 | }, |
||
935 | |||
936 | /** Get the data of `list`, by searching `indexID` in `indexArr`, or return `defaultVal` if not found */ |
||
937 | getByMatchingArray: function(indexArr, indexID, defaultVal = null){ |
||
938 | var list = this; |
||
939 | var slot = indexArr.indexOf(indexID); |
||
940 | return slot == -1 ? defaultVal : list[slot]; |
||
941 | }, |
||
942 | /** Set the data of `list`, by searching `indexID` in `indexArr` */ |
||
943 | setByMatchingArray: function(indexArr, indexID, data){ |
||
944 | var list = this; |
||
945 | var slot = indexArr.indexOf(indexID); |
||
946 | if (slot == -1) { |
||
947 | return false; |
||
948 | } |
||
949 | list[slot] = data; |
||
950 | return true; |
||
951 | }, |
||
952 | |||
953 | page: function(page, pageLength, invisibleRows = null){ |
||
954 | var list = this; |
||
955 | |||
956 | // ensure page no. in limits |
||
957 | var lastPage = Math.ceil(list.length / pageLength); |
||
958 | page = page.limitTo(0, lastPage - 1); |
||
959 | |||
960 | // get first/last row in page |
||
961 | var pageStart = page*pageLength;/// 0-based - first row in page |
||
962 | var pageEnd = (pageStart + pageLength) - 1;/// 0-based - last row in page |
||
963 | |||
964 | // get on-page rows |
||
965 | var visibleRows = list.getRange(pageStart, pageLength); |
||
966 | |||
967 | // get off-page rows |
||
968 | if (invisibleRows) { |
||
969 | invisibleRows.addRange(list, 0, pageStart - 1); |
||
970 | invisibleRows.addRange(list, pageEnd + 1, list.length - 1); |
||
971 | } |
||
972 | |||
973 | return visibleRows; |
||
974 | }, |
||
975 | |||
976 | trim: function(returnNew = false, trimVal = null){ |
||
977 | var list = this; |
||
978 | var first = IndexOf(list, trimVal, true); |
||
979 | if (first == -1) { |
||
980 | if (returnNew) { |
||
981 | return []; |
||
982 | }else { |
||
983 | list.length = 0; |
||
984 | } |
||
985 | }else{ |
||
986 | var last = list.lastIndexOf(trimVal, true); |
||
987 | if (returnNew) { |
||
988 | return GetManySE(list, first, last); |
||
989 | }else { |
||
990 | |||
991 | if (first != -1 && first != 0){ |
||
1 ignored issue
–
show
|
|||
992 | DeleteManySE(list, 0, first-1); |
||
993 | } |
||
994 | if (last != -1){ |
||
995 | list.length = last - first + 1; |
||
996 | } |
||
997 | } |
||
998 | } |
||
999 | return list; |
||
1000 | }, |
||
1001 | |||
1002 | trimLeft: function(returnNew = false, trimVal = null){ |
||
1003 | var list = this; |
||
1004 | var first = IndexOf(list, trimVal, true); |
||
1005 | if (first == -1) { |
||
1006 | if (returnNew) { |
||
1007 | return []; |
||
1008 | }else { |
||
1009 | list.length = 0; |
||
1010 | } |
||
1011 | }else{ |
||
1012 | if (returnNew) { |
||
1013 | return GetAfter(list, first); |
||
1014 | }else { |
||
1015 | if (first != -1 && first != 0){ |
||
1 ignored issue
–
show
|
|||
1016 | DeleteManySE(list, 0, first-1); |
||
1017 | } |
||
1018 | } |
||
1019 | } |
||
1020 | return list; |
||
1021 | }, |
||
1022 | trimRight: function(returnNew = false, trimVal = null){ |
||
1023 | var list = this; |
||
1024 | var last = IndexOf(list, trimVal, true); |
||
1025 | if (last == -1) { |
||
1026 | if (returnNew) { |
||
1027 | return []; |
||
1028 | }else { |
||
1029 | list.length = 0; |
||
1030 | } |
||
1031 | }else{ |
||
1032 | if (returnNew) { |
||
1033 | return GetBefore(list, last); |
||
1034 | }else { |
||
1035 | list.length = last + 1; |
||
1036 | } |
||
1037 | } |
||
1038 | return list; |
||
1039 | }, |
||
1040 | |||
1041 | transpose: function() { |
||
1042 | var arr = this; |
||
1043 | var transposed = []; |
||
1044 | |||
1045 | for (var r = 0; r < arr.length; r++) { |
||
1046 | for (var c = 0; c < arr[r].length; c++) { |
||
1047 | if (transposed[c] == null) { |
||
1 ignored issue
–
show
|
|||
1048 | transposed[c] = []; |
||
1049 | } |
||
1050 | transposed[c][r] = arr[r][c]; |
||
1051 | } |
||
1052 | } |
||
1053 | |||
1054 | return transposed; |
||
1055 | }, |
||
1056 | |||
1057 | |||
1058 | none:null |
||
1059 | }; |
||
1060 | |||
1061 | // register funcs |
||
1062 | UB.registerFuncs(Array.prototype, arrayFuncs); |
||
1063 |