Total Complexity | 192 |
Complexity/F | 4.09 |
Lines of Code | 916 |
Function Count | 47 |
Duplicated Lines | 99 |
Ratio | 10.81 % |
Changes | 3 | ||
Bugs | 2 | 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.core.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 */ |
||
6 | var arrayFuncs = { |
||
7 | |||
8 | View Code Duplication | count: function(value, not = false){ |
|
|
|||
9 | var list = this; |
||
10 | var total = 0; |
||
11 | for (var a = 0, al = list.length;a<al;a++){ |
||
12 | if (not) { |
||
13 | if (list[a] != value) { |
||
14 | total++; |
||
15 | } |
||
16 | }else { |
||
17 | if (list[a] == value) { |
||
18 | total++; |
||
19 | } |
||
20 | } |
||
21 | } |
||
22 | return total; |
||
23 | }, |
||
24 | or: function(list2){ |
||
25 | var list = this; |
||
26 | if (list.exists()) { |
||
27 | return list; |
||
28 | } |
||
29 | return list2; |
||
30 | }, |
||
31 | |||
32 | part: function(start, end){ |
||
33 | var list = this; |
||
34 | |||
35 | // quickly exit if no items or no results possible |
||
36 | if (list == null || list.length === 0 || start > end || start >= list.length) { |
||
37 | return []; |
||
38 | } |
||
39 | |||
40 | // just get the part we need |
||
41 | return list.slice(start, end + 1); |
||
42 | }, |
||
43 | |||
44 | swap: function(slot1, slot2){ |
||
45 | var list = this; |
||
46 | var temp = list[slot2]; |
||
47 | list[slot2] = list[slot1]; |
||
48 | list[slot1] = temp; |
||
49 | }, |
||
50 | |||
51 | add: function(item){ |
||
52 | var list = this; |
||
53 | list.push(item); |
||
54 | return list.length - 1; |
||
55 | }, |
||
56 | addToStart: function(item){ |
||
57 | var list = this; |
||
58 | list.unshift(item); |
||
59 | return 0; |
||
60 | }, |
||
61 | /** return false if item exists, true if item does not */ |
||
62 | addOnce: function(value){ |
||
63 | var list = this; |
||
64 | |||
65 | // return false if item exists |
||
66 | if (list.indexOf(value) > -1) { |
||
67 | return false; |
||
68 | } |
||
69 | |||
70 | // add if not found |
||
71 | list.push(value); |
||
72 | return true; |
||
73 | }, |
||
74 | |||
75 | addArray: function(toAdd, addAtSlot = -1, modifyMain = true){ |
||
76 | var list = this; |
||
77 | |||
78 | if (toAdd != null && toAdd.length > 0) { |
||
79 | if (!modifyMain) { |
||
80 | list = list.concat(); /// shallow clone |
||
81 | } |
||
82 | |||
83 | // set length first so allocates memory (maybe?) |
||
84 | var origLen = list.length; |
||
85 | if (addAtSlot === -1){ |
||
86 | list.length += toAdd.length; |
||
87 | } |
||
88 | |||
89 | // set all slots |
||
90 | var next = addAtSlot === -1 ? origLen : addAtSlot; |
||
91 | for (var a = 0, al = toAdd.length;a<al;a++, next++){ |
||
92 | list[next] = toAdd[a]; |
||
93 | } |
||
94 | } |
||
95 | return list; |
||
96 | }, |
||
97 | |||
98 | /** adds the given value many times */ |
||
99 | addManyTimes: function(val, times){ |
||
100 | var list = this; |
||
101 | |||
102 | if (times <= 0) { |
||
103 | return list; |
||
104 | } |
||
105 | |||
106 | var n = list.length; |
||
107 | for (var t = 0;t<times;t++){ |
||
108 | list[n++] = val; |
||
109 | } |
||
110 | |||
111 | return list; |
||
112 | }, |
||
113 | |||
114 | addRange: function(toAdd, startSlot, endSlot){ |
||
115 | var list = this; |
||
116 | |||
117 | // exit if no work |
||
118 | if (endSlot < startSlot) { |
||
119 | return; |
||
120 | } |
||
121 | |||
122 | // per wanted slot of the `add` array |
||
123 | startSlot = startSlot.limitToArray(toAdd); |
||
124 | endSlot = endSlot.limitToArray(toAdd); |
||
125 | for (var s = startSlot;s <= endSlot;s++){ |
||
126 | |||
127 | // add into `main` array |
||
128 | list.push(toAdd[s]); |
||
129 | |||
130 | } |
||
131 | }, |
||
132 | |||
133 | /** returns final index of added item, or index of already existing item */ |
||
134 | findOrAdd: function(value){ |
||
135 | var list = this; |
||
136 | |||
137 | // return index of item if exists |
||
138 | var i = list.indexOf(value); |
||
139 | if (i > -1) { |
||
140 | return i; |
||
141 | } |
||
142 | |||
143 | // add if not found |
||
144 | i = list.length; |
||
145 | list[i] = value; |
||
146 | return i; |
||
147 | }, |
||
148 | |||
149 | insertOne: function(item, slot){ |
||
150 | var list = this; |
||
151 | |||
152 | // adds one slot at the given point |
||
153 | // modifies the main array |
||
154 | |||
155 | list.splice(slot, 0, item); |
||
156 | }, |
||
157 | |||
158 | /** if slot = -1 or outside the array, the item is added to the END of the array. |
||
159 | * Otherwise the item is added at the given slot. */ |
||
160 | insertOneOrAdd: function(item, slot){ |
||
161 | var list = this; |
||
162 | |||
163 | // adds one slot at the given point |
||
164 | // modifies the main array |
||
165 | |||
166 | if (slot < 0 || slot >= list.length) { |
||
167 | list.push(item); |
||
168 | return list.length - 1; |
||
169 | } |
||
170 | list.splice(slot, 0, item); |
||
171 | return slot; |
||
172 | }, |
||
173 | insertArray: function(newItems, slot, returnNew = true){ |
||
174 | var list = this; |
||
175 | |||
176 | // adds many slots at the given point |
||
177 | // returns a new array |
||
178 | if(returnNew){ |
||
179 | return list.slice(0, slot).concat(newItems).concat(list.slice(slot)); |
||
180 | } |
||
181 | |||
182 | // adds many slots at the given point |
||
183 | // modifies the main array |
||
184 | for (var a = 0, al = newItems.length;a<al;a++){ |
||
185 | list.splice(slot++, 0, newItems[a]); |
||
186 | } |
||
187 | return list; |
||
188 | }, |
||
189 | insertArrayAfter: function(newItems, after){ |
||
190 | var list = this; |
||
191 | if (list.isLast(after)) { |
||
192 | list.addArray(newItems); |
||
193 | } else { |
||
194 | var i = list.indexOf(after); |
||
195 | list.insertArray(i + 1, newItems); |
||
196 | } |
||
197 | }, |
||
198 | |||
199 | |||
200 | removeAndInsert: function(from, to){ |
||
201 | var list = this; |
||
202 | |||
203 | // ensure slots within array |
||
204 | var al = list.length; |
||
205 | from = from.limitTo(0, al - 1); |
||
206 | to = to.limitTo(0, al - 1); |
||
207 | if (to < from) { |
||
208 | var i1 = to; |
||
209 | var i2 = from; |
||
210 | }else { |
||
211 | i1 = from; |
||
212 | i2 = to; |
||
213 | } |
||
214 | |||
215 | // fill unaffected header |
||
216 | var result = []; |
||
217 | if(i1 > 0){ |
||
218 | for (var a = 0;a<i1;a++){ |
||
219 | result[a] = list[a]; |
||
220 | } |
||
221 | } |
||
222 | |||
223 | // fill "to" |
||
224 | result[to] = list[from]; |
||
225 | |||
226 | // fill between from and to |
||
227 | if(to < from){ |
||
228 | for (a = to + 1; a <= from; a++) { |
||
229 | result[a] = list[a - 1]; |
||
230 | } |
||
231 | }else { |
||
232 | for (a = from; a < to; a++) { |
||
233 | result[a] = list[a + 1]; |
||
234 | } |
||
235 | } |
||
236 | |||
237 | // fill unaffected footer |
||
238 | for (var a = i2 + 1;a<al;a++){ |
||
239 | result[a] = list[a]; |
||
240 | } |
||
241 | |||
242 | return result; |
||
243 | }, |
||
244 | |||
245 | /** replace a range of items with a given array */ |
||
246 | replaceRange: function(replaceStartSlot, replaceEndSlot, newItems, returnNew = true){ |
||
247 | var list = this; |
||
248 | |||
249 | |||
250 | // simply remove a single item |
||
251 | if (replaceStartSlot == replaceEndSlot && newItems.length === 0) { |
||
252 | if (returnNew) { |
||
253 | list = list.concat(); |
||
254 | } |
||
255 | list.splice(replaceStartSlot, 1); |
||
256 | return list; |
||
257 | |||
258 | // simply replace a single item |
||
259 | }else if (replaceStartSlot == replaceEndSlot && newItems.length === 1) { |
||
260 | if (returnNew) { |
||
261 | list = list.concat(); |
||
262 | } |
||
263 | list[replaceStartSlot] = newItems[0]; |
||
264 | return list; |
||
265 | |||
266 | } |
||
267 | |||
268 | // alt method if returning a new array |
||
269 | if(returnNew){ |
||
270 | return list.slice(0, replaceStartSlot).concat(newItems).concat(list.slice(replaceEndSlot + 1)); |
||
271 | } |
||
272 | |||
273 | // remove many |
||
274 | list.splice(replaceStartSlot, (replaceEndSlot - replaceStartSlot) + 1); |
||
275 | |||
276 | // insert many |
||
277 | var slot = replaceStartSlot; |
||
278 | for (var a = 0, al = newItems.length;a<al;a++){ |
||
279 | list.splice(slot++, 0, newItems[a]); |
||
280 | } |
||
281 | return list; |
||
282 | }, |
||
283 | |||
284 | |||
285 | splitAt: function(slot, includeSlot = false, includeInFirst = false){ |
||
286 | var list = this; |
||
287 | if (includeSlot) { |
||
288 | if (includeInFirst) { |
||
289 | return [list.slice(0, slot + 1), list.slice(slot + 1)]; |
||
290 | } |
||
291 | return [list.slice(0, slot), list.slice(slot)]; |
||
292 | } |
||
293 | return [list.slice(0, slot), list.slice(slot+1)]; |
||
294 | }, |
||
295 | splitAtEvery: function(seperator){ |
||
296 | var list = this; |
||
297 | var splits = []; |
||
298 | var lastSlot = 0; |
||
299 | for (var a = 0, al = list.length;a<al;a++){ |
||
300 | if (list[a] == seperator && a > lastSlot) { |
||
301 | splits.push(list.slice(lastSlot, a)); |
||
302 | lastSlot = a + 1; |
||
303 | } |
||
304 | } |
||
305 | return splits; |
||
306 | }, |
||
307 | |||
308 | moveToTop: function(slot, returnNew = false){ |
||
309 | var list = this; |
||
310 | |||
311 | View Code Duplication | if (returnNew){ |
|
312 | |||
313 | // ALWAYS RETURNS NEW ARRAY |
||
314 | |||
315 | // exit quickly if slot not in array |
||
316 | var al = list.length; |
||
317 | if (slot < 0 || slot >= al) { |
||
318 | return list.concat(); |
||
319 | } |
||
320 | |||
321 | // create new array with slot on top |
||
322 | var newArr = [list[slot]]; |
||
323 | var n = 1; |
||
324 | |||
325 | // add all other slots |
||
326 | for (var a = 0;a<al;a++){ |
||
327 | if (a != slot) { |
||
328 | newArr[n++] = list[a]; |
||
329 | } |
||
330 | } |
||
331 | |||
332 | return newArr; |
||
333 | } |
||
334 | |||
335 | |||
336 | // MODIFIES ARRAY IN PLACE |
||
337 | |||
338 | // exit quickly if slot not in array |
||
339 | var al = list.length; |
||
340 | if (slot < 0 || slot >= al) { |
||
341 | return; |
||
342 | } |
||
343 | |||
344 | // delete and re-add slot |
||
345 | var val = list[slot]; |
||
346 | list.splice(slot, 1); |
||
347 | list.unshift(val); |
||
348 | }, |
||
349 | moveToBottom: function(slot, returnNew = false){ |
||
350 | var list = this; |
||
351 | |||
352 | View Code Duplication | if (returnNew){ |
|
353 | |||
354 | // ALWAYS RETURNS NEW ARRAY |
||
355 | |||
356 | // exit quickly if slot not in array |
||
357 | var al = list.length; |
||
358 | if (slot < 0 || slot >= al) { |
||
359 | return list.concat(); |
||
360 | } |
||
361 | |||
362 | // create new array with slot on top |
||
363 | var newArr = []; |
||
364 | var n = 0; |
||
365 | |||
366 | // add all other slots |
||
367 | for (var a = 0;a<al;a++){ |
||
368 | if (a != slot) { |
||
369 | newArr[n++] = list[a]; |
||
370 | } |
||
371 | } |
||
372 | |||
373 | // add slot to bottom |
||
374 | newArr[n++] = list[slot]; |
||
375 | return newArr; |
||
376 | |||
377 | } |
||
378 | |||
379 | // MODIFIES ARRAY IN PLACE |
||
380 | |||
381 | // exit quickly if slot not in array |
||
382 | var al = list.length; |
||
383 | if (slot < 0 || slot >= al) { |
||
384 | return; |
||
385 | } |
||
386 | |||
387 | // delete and re-add slot |
||
388 | var val = list[slot]; |
||
389 | list.splice(slot, 1); |
||
390 | list.push(val); |
||
391 | }, |
||
392 | moveUp: function(item){ |
||
393 | var list = this; |
||
394 | |||
395 | // MODIFIES ARRAY IN PLACE |
||
396 | |||
397 | // exit quickly if slot not in array, or already on top |
||
398 | var slot = list.indexOf(item); |
||
399 | if (slot <= 0) { |
||
400 | return false; |
||
401 | } |
||
402 | |||
403 | // move one up |
||
404 | list.swap(slot, slot - 1); |
||
405 | return true; |
||
406 | }, |
||
407 | moveDown: function(item){ |
||
408 | var list = this; |
||
409 | |||
410 | // MODIFIES ARRAY IN PLACE |
||
411 | |||
412 | // exit quickly if slot not in array, or already at bottom |
||
413 | var al = list.length; |
||
414 | var slot = list.indexOf(item); |
||
415 | if (slot < 0 || slot >= (al - 1)) { |
||
416 | return false; |
||
417 | } |
||
418 | |||
419 | // move one down |
||
420 | list.swap(slot, slot + 1); |
||
421 | return true; |
||
422 | }, |
||
423 | moveSlotUp: function(slot){ |
||
424 | var list = this; |
||
425 | |||
426 | // MODIFIES ARRAY IN PLACE |
||
427 | |||
428 | // exit quickly if slot not in array, or already on top |
||
429 | var al = list.length; |
||
430 | if (slot <= 0 || slot >= al) { |
||
431 | return false; |
||
432 | } |
||
433 | |||
434 | // move one up |
||
435 | list.swap(slot, slot - 1); |
||
436 | return true; |
||
437 | }, |
||
438 | moveSlotDown: function(slot){ |
||
439 | var list = this; |
||
440 | |||
441 | // MODIFIES ARRAY IN PLACE |
||
442 | |||
443 | // exit quickly if slot not in array, or already at bottom |
||
444 | var al = list.length; |
||
445 | if (slot < 0 || slot >= (al - 1)) { |
||
446 | return false; |
||
447 | } |
||
448 | |||
449 | // move one down |
||
450 | list.swap(slot, slot + 1); |
||
451 | return true; |
||
452 | }, |
||
453 | |||
454 | /** Move an item from the given list, to the start/end of the target list */ |
||
455 | moveToArray: function(item, toList, evenIfExists = false, addToEnd = true){ |
||
456 | var list = this; |
||
457 | |||
458 | // remove from source list |
||
459 | RemoveOne(list, item); |
||
460 | |||
461 | // add to target list |
||
462 | if (evenIfExists || toList.indexOf(item) === -1) { |
||
463 | if (addToEnd) { |
||
464 | toList.push(item); |
||
465 | }else{ |
||
466 | toList.unshift(item); |
||
467 | } |
||
468 | return true; |
||
469 | } |
||
470 | |||
471 | return false; |
||
472 | }, |
||
473 | |||
474 | |||
475 | /** Returns the nearest existing slot value in the array. Returns `ifNoSlots` if the array is empty. */ |
||
476 | within: function(slot, ifNoSlots = null){ |
||
477 | var list = this; |
||
478 | |||
479 | // return null if array empty |
||
480 | var len = list.length; |
||
481 | if (len === 0) { |
||
482 | return ifNoSlots; |
||
483 | } |
||
484 | |||
485 | // return first slot if index negative |
||
486 | if (slot < 0) { |
||
487 | return list[0]; |
||
488 | } |
||
489 | |||
490 | // return last slot if index more than last slot |
||
491 | if (slot >= len) { |
||
492 | return list[len - 1]; |
||
493 | } |
||
494 | |||
495 | // return given slot if within array |
||
496 | return list[slot]; |
||
497 | }, |
||
498 | |||
499 | first: function(list){ |
||
500 | var list = this; |
||
501 | var len = list.length; |
||
502 | if (len === 0) { |
||
503 | return null; |
||
504 | } |
||
505 | return list[0]; |
||
506 | }, |
||
507 | firstExisting: function(slots, blankVal = null){ |
||
508 | var list = this; |
||
509 | for (var s = 0, sl = slots.length;s<sl;s++){ |
||
510 | var val; |
||
511 | if ((val = list[slots[s]]) != blankVal) { |
||
512 | return val; |
||
513 | } |
||
514 | } |
||
515 | return null; |
||
516 | }, |
||
517 | last: function(list){ |
||
518 | var list = this; |
||
519 | var len = list.length; |
||
520 | if (len === 0) { |
||
521 | return null; |
||
522 | } |
||
523 | return list[len-1]; |
||
524 | }, |
||
525 | lastX: function(count){ |
||
526 | var list = this; |
||
527 | var s = (0).max(list.length - count); |
||
528 | return list.slice(s, list.length); |
||
529 | }, |
||
530 | setFirst: function(value){ |
||
531 | var list = this; |
||
532 | var len = list.length; |
||
533 | if (len === 0) { |
||
534 | return; |
||
535 | } |
||
536 | list[0] = value; |
||
537 | }, |
||
538 | setLast: function(value){ |
||
539 | var list = this; |
||
540 | var len = list.length; |
||
541 | if (len === 0) { |
||
542 | return; |
||
543 | } |
||
544 | list[len-1] = value; |
||
545 | }, |
||
546 | |||
547 | random: function(list){ |
||
548 | var list = this; |
||
549 | |||
550 | // return null if array empty |
||
551 | if (list.length === 0) { |
||
552 | return null; |
||
553 | } |
||
554 | |||
555 | // return random slot within array |
||
556 | return list[parseInt(Math.random() * 1000000) % list.length]; |
||
557 | }, |
||
558 | |||
559 | View Code Duplication | pick: function(slots){ |
|
560 | var list = this; |
||
561 | var out = []; |
||
562 | |||
563 | if (!slots){ |
||
564 | return out; |
||
565 | } |
||
566 | |||
567 | for (var i = 0, il = slots.length;i<il;i++){ |
||
568 | id = slots[i]; |
||
569 | val = list[id]; |
||
570 | if (val != null) { |
||
571 | out.push(val); |
||
572 | } |
||
573 | } |
||
574 | return out; |
||
575 | }, |
||
576 | |||
577 | View Code Duplication | pickMatching: function(slots, evenIfNull = false){ |
|
578 | var list = this; |
||
579 | var out = []; |
||
580 | |||
581 | if (!slots){ |
||
582 | return out; |
||
583 | } |
||
584 | |||
585 | for (var i = 0, il = slots.length;i<il;i++){ |
||
586 | id = slots[i]; |
||
587 | val = list[id]; |
||
588 | if (val != null || evenIfNull) { |
||
589 | out[id] = val; |
||
590 | } |
||
591 | } |
||
592 | return out; |
||
593 | }, |
||
594 | |||
595 | /** Get the data of `list`, by searching `indexID` in `indexArr`, or return `defaultVal` if not found */ |
||
596 | getByMatchingArray: function(indexArr, indexID, defaultVal = null){ |
||
597 | var list = this; |
||
598 | var slot = indexArr.indexOf(indexID); |
||
599 | return slot === -1 ? defaultVal : list[slot]; |
||
600 | }, |
||
601 | /** Set the data of `list`, by searching `indexID` in `indexArr` */ |
||
602 | setByMatchingArray: function(indexArr, indexID, data){ |
||
603 | var list = this; |
||
604 | var slot = indexArr.indexOf(indexID); |
||
605 | if (slot === -1) { |
||
606 | return false; |
||
607 | } |
||
608 | list[slot] = data; |
||
609 | return true; |
||
610 | }, |
||
611 | |||
612 | page: function(page, pageLength, invisibleRows = null){ |
||
613 | var list = this; |
||
614 | |||
615 | // ensure page no. in limits |
||
616 | var lastPage = Math.ceil(list.length / pageLength); |
||
617 | page = page.limitTo(0, lastPage - 1); |
||
618 | |||
619 | // get first/last row in page |
||
620 | var pageStart = page*pageLength;/// 0-based - first row in page |
||
621 | var pageEnd = (pageStart + pageLength) - 1;/// 0-based - last row in page |
||
622 | |||
623 | // get on-page rows |
||
624 | var visibleRows = list.part(pageStart, pageLength); |
||
625 | |||
626 | // get off-page rows |
||
627 | if (invisibleRows) { |
||
628 | invisibleRows.addRange(list, 0, pageStart - 1); |
||
629 | invisibleRows.addRange(list, pageEnd + 1, list.length - 1); |
||
630 | } |
||
631 | |||
632 | return visibleRows; |
||
633 | }, |
||
634 | |||
635 | transpose: function() { |
||
636 | var arr = this; |
||
637 | var transposed = []; |
||
638 | |||
639 | for (var r = 0; r < arr.length; r++) { |
||
640 | for (var c = 0; c < arr[r].length; c++) { |
||
641 | if (transposed[c] == null) { |
||
642 | transposed[c] = []; |
||
643 | } |
||
644 | transposed[c][r] = arr[r][c]; |
||
645 | } |
||
646 | } |
||
647 | |||
648 | return transposed; |
||
649 | }, |
||
650 | |||
651 | |||
652 | // fast sorting |
||
653 | quickSort: function(ascending = true){ |
||
654 | var input = this; |
||
655 | |||
656 | var len = input.length; |
||
657 | if (len >= 2) { |
||
658 | |||
659 | // sort in place |
||
660 | input._quickSort(0, len - 1, 0); |
||
661 | |||
662 | // flip if descending wanted |
||
663 | if (!ascending) { |
||
664 | input.reverse(); |
||
665 | } |
||
666 | |||
667 | } |
||
668 | }, |
||
669 | |||
670 | indexedQuickSort: function(ascending = true){ |
||
671 | var input = this; |
||
672 | |||
673 | var len = input.length; |
||
674 | if (len >= 2) { |
||
675 | |||
676 | // indexed sort |
||
677 | var index = UB.newArray(0, input.length); |
||
678 | input._indexedQuickSort(index, 0, len - 1, 0); |
||
679 | |||
680 | // flip if descending wanted |
||
681 | if (!ascending) { |
||
682 | index.reverse(); |
||
683 | } |
||
684 | |||
685 | return index; |
||
686 | } |
||
687 | |||
688 | return null; |
||
689 | }, |
||
690 | |||
691 | /** INTERNAL FUNCTION, do not use directly */ |
||
692 | _quickSort: function(left, right, d){ |
||
693 | var input = this; |
||
694 | if (left >= right){ |
||
695 | return; |
||
696 | } |
||
697 | var j = right, i = left; |
||
698 | var size = right - left; |
||
699 | //var pivotPoint = input[uint((right>>>1) + (left>>>1))], t; |
||
700 | var pivotPoint = input[((right>>>1) + (left>>>1)) >>> 0], t; |
||
701 | do { |
||
702 | if (size < 9) { |
||
703 | pivotPoint = input[left]; |
||
704 | do { |
||
705 | do { |
||
706 | left++; |
||
707 | if (input[left] < pivotPoint) { |
||
708 | pivotPoint = input[left]; |
||
709 | do { // this section can be improved. |
||
710 | input[left--] = input[left]; |
||
711 | } while (left > i && pivotPoint < input[left]); |
||
712 | input[left] = pivotPoint; |
||
713 | } |
||
714 | } while (left < right); |
||
715 | i++; |
||
716 | left = i; |
||
717 | pivotPoint = input[left]; |
||
718 | } while (i < right); |
||
719 | return; |
||
720 | } |
||
721 | while (left < right) { |
||
722 | if (input[right] > pivotPoint){ |
||
723 | do { right--; } |
||
724 | while (input[right] > pivotPoint); |
||
725 | } |
||
726 | if (input[left] < pivotPoint){ |
||
727 | do { left++; } |
||
728 | while (input[left] < pivotPoint); |
||
729 | } |
||
730 | if (left < right) { |
||
731 | t = input[left]; |
||
732 | input[left] = input[right]; |
||
733 | input[right] = t; |
||
734 | left++; |
||
735 | right--; |
||
736 | } |
||
737 | } |
||
738 | if (right) { |
||
739 | if (left === right) { |
||
740 | if (input[left] < pivotPoint){ |
||
741 | left++; |
||
742 | }else if (input[right] > pivotPoint){ |
||
743 | right--; |
||
744 | } |
||
745 | } |
||
746 | if (i < right) { |
||
747 | input._quickSort(i, right, d + 1); |
||
748 | } |
||
749 | } |
||
750 | left |= int(!left) & int(!right); |
||
751 | if (j <= left){ |
||
752 | return; |
||
753 | } |
||
754 | i = left; |
||
755 | right = j; |
||
756 | //pivotPoint = input[uint((right >>> 1) + (left >>> 1))]; |
||
757 | pivotPoint = input[((right >>> 1) + (left >>> 1)) >>> 0]; |
||
758 | size = right - left; |
||
759 | d++; |
||
760 | } while (true); |
||
761 | }, |
||
762 | |||
763 | /** INTERNAL FUNCTION, do not use directly */ |
||
764 | _indexedQuickSort: function(indexed, left, right, d){ |
||
765 | var input = this; |
||
766 | if (left >= right){ |
||
767 | return; |
||
768 | } |
||
769 | |||
770 | // status |
||
771 | var j; |
||
772 | var i; |
||
773 | var size = (j = right) - (i = left); |
||
774 | //var pivotPoint = (input[uint((right>>>1) + (left>>>1))]); |
||
775 | var pivotPoint = (input[((right>>>1) + (left>>>1)) >>> 0]); |
||
776 | |||
777 | // temps |
||
778 | var pivotIndex; |
||
779 | var temp; |
||
780 | var temp2; |
||
781 | |||
782 | do { |
||
783 | |||
784 | //{ part 1 |
||
785 | if (size < 9) { |
||
786 | pivotPoint = input[left]; |
||
787 | do { |
||
788 | do { |
||
789 | left++; |
||
790 | temp = input[left]; |
||
791 | if (temp < pivotPoint) { |
||
792 | |||
793 | pivotIndex = indexed[left]; |
||
794 | pivotPoint = temp; |
||
795 | |||
796 | do { |
||
797 | |||
798 | // change vals |
||
799 | input[left] = input[left - 1]; |
||
800 | |||
801 | // change indices |
||
802 | indexed[left] = indexed[left - 1]; |
||
803 | |||
804 | left--; |
||
805 | |||
806 | } while (left > i && pivotPoint < input[left]); |
||
807 | |||
808 | // change vals |
||
809 | input[left] = pivotPoint; |
||
810 | |||
811 | // change indices |
||
812 | indexed[left] = pivotIndex; |
||
813 | } |
||
814 | } while (left < right); |
||
815 | i++; |
||
816 | pivotPoint = input[left = i]; |
||
817 | } while (i < right); |
||
818 | return; |
||
819 | } |
||
820 | //} |
||
821 | |||
822 | //{ part 2 |
||
823 | while (left < right) { |
||
824 | if (input[right] > pivotPoint) { |
||
825 | do { |
||
826 | right--; |
||
827 | } while (input[right] > pivotPoint); |
||
828 | } |
||
829 | if (input[left] < pivotPoint) { |
||
830 | do { |
||
831 | left++; |
||
832 | } while (input[left] < pivotPoint); |
||
833 | } |
||
834 | if (left < right) { |
||
835 | |||
836 | // flip values |
||
837 | temp = input[left]; |
||
838 | input[left] = input[right]; |
||
839 | input[right] = temp; |
||
840 | |||
841 | // flip indices |
||
842 | temp2 = indexed[left]; |
||
843 | indexed[left] = indexed[right]; |
||
844 | indexed[right] = temp2; |
||
845 | |||
846 | left++; |
||
847 | right--; |
||
848 | } |
||
849 | } |
||
850 | //} |
||
851 | |||
852 | //{ part 2 |
||
853 | if (right) { |
||
854 | if (left === right) { |
||
855 | if (input[left] < pivotPoint) { |
||
856 | left++; |
||
857 | }else if (input[right] > pivotPoint) { |
||
858 | right--; |
||
859 | } |
||
860 | } |
||
861 | if (i < right) { |
||
862 | |||
863 | // recurse |
||
864 | input._indexedQuickSort(indexed, i, right, d + 1); |
||
865 | |||
866 | } |
||
867 | } |
||
868 | //} |
||
869 | |||
870 | left |= int(!left) & int(!right); |
||
871 | if (j <= left) { |
||
872 | return; |
||
873 | } |
||
874 | i = left; |
||
875 | right = j; |
||
876 | //pivotPoint = input[uint((right >>> 1) + (left >>> 1))]; |
||
877 | pivotPoint = input[((right >>> 1) + (left >>> 1)) >>> 0]; |
||
878 | size = right - left; |
||
879 | d++; |
||
880 | } while (true); |
||
881 | }, |
||
882 | |||
883 | |||
884 | next: function(obj, wrap = false){ |
||
885 | var list = this; |
||
886 | if (list == null) { |
||
887 | return null; |
||
888 | } |
||
889 | var i = list.indexOf(obj); |
||
890 | if (i > -1) { |
||
891 | return (wrap && i >= (list.length - 1)) ? list[0] : list[i + 1]; |
||
892 | } |
||
893 | return null; |
||
894 | }, |
||
895 | prev: function(obj, wrap = false){ |
||
896 | var list = this; |
||
897 | if (list == null) { |
||
898 | return null; |
||
899 | } |
||
900 | var i = list.indexOf(obj); |
||
901 | if (i > 0) { |
||
902 | return wrap ? list[list.length - 1] : list[i - 1]; |
||
903 | } |
||
904 | return null; |
||
905 | }, |
||
906 | |||
907 | |||
908 | get: function(slot, defaultVal){ |
||
909 | var list = this; |
||
910 | var val = list[slot]; |
||
911 | if (val == null) { |
||
912 | return defaultVal; |
||
913 | } |
||
914 | return val; |
||
915 | }, |
||
916 | |||
917 | none:null |
||
918 | }; |
||
919 | |||
920 | // register funcs |
||
921 | UB.registerFuncs(Array.prototype, arrayFuncs); |
||
922 |