Created
July 28, 2016 15:46
-
-
Save uolcano/c13abf236321ce344ee5a4585145c05b to your computer and use it in GitHub Desktop.
Customized integrated array looper[index-specified, support forwards or backwards, break and continue]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************************************************************** | |
* @param {Array} [arr] [the array to be iterated] | |
* | |
* @param {Function} [process] [the callback to process the element in array] | |
* (elm, idx, arr, resolve) | |
* @description [process(elm, idx, arr, resolve) { return true; // return true to terminate current loop }] | |
* | |
* @param {Object} [options] [the iteration configurations] | |
* {loopStart, loopEnd, travType} | |
* @description [loopStart inclusive the index, loopEnd exclusive the index] | |
* | |
* @param {Object} [context] [the context which callback bound to] | |
* | |
***************************************************************************************************/ | |
function combineLoop(arr, process, options, context) { | |
'use strict'; | |
typeof options === 'undefined' && (options = {}); | |
var __LOOP_LMT = 200; // limit the loop count | |
var __arr_tmp = arr || [], // the current looping array | |
__arr_rlt = [], // the result arr to return | |
__arr_len = __arr_tmp.length || 0, | |
__start = options.loopStart > 0 ? Number(options.loopStart) : 0, | |
__end = options.loopEnd > -2 ? Number(options.loopEnd) : __arr_len, | |
__index = __start, // the current looping index | |
__cond_expr = '', // condition expression | |
__asc_flag = 1, // label the ascendent or descendent order | |
__trav_type = typeof options.travType === 'undefined' ? 'ALL' : options.travType, // mark the loop whether to break or continue, by default 'ALL' means completely looping | |
__crt_itm, // the current looping element | |
__rtn = false; // determine the process return a true, to help decide whether to break or continue | |
// get data from the callback | |
function __resolve(itm, idx, arr) { | |
typeof itm === 'undefined' || (__crt_itm = itm); | |
typeof idx === 'undefined' || (__index = idx); | |
typeof arr === 'undefined' || __arr_tmp === arr && (__arr_tmp = arr); | |
} | |
__resolve.states = {}; // cache some special states from process callback | |
if (!__arr_len) return; | |
if (typeof process !== 'function') return; | |
if (__start > __arr_len) { | |
__start = __arr_len - 1; | |
console.log('loopStart more than the max-index of the array!'); | |
__index = __start; | |
} | |
if (__end > __arr_len) { | |
__end = __arr_len; | |
console.log('loopEnd more than the max-index of the array!'); | |
} | |
if (__end - __start > 0) { | |
__cond_expr = '__index<__end'; | |
__asc_flag = 1; | |
} else if (__end - __start < 0) { | |
__cond_expr = '__index>__end'; | |
__asc_flag = -1; | |
} | |
// label for break or continue | |
sentinel: | |
do { | |
__crt_itm = __arr_tmp[__index]; | |
__rtn = process.call(context, __crt_itm, __index, __arr_tmp, __resolve); | |
__index += __asc_flag; | |
if (__rtn) { | |
switch (__trav_type.toUpperCase()) { | |
case 'BREAK': | |
break sentinel; | |
case 'CONTINUE': | |
continue sentinel; | |
} | |
} | |
__arr_rlt.push(__crt_itm); | |
} while (--__LOOP_LMT && eval(__cond_expr)); | |
__asc_flag < 0 && __arr_rlt.reverse(); | |
return __arr_rlt; | |
} | |
/******************************************** | |
Demostration | |
********************************************/ | |
var test_arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 17, 19, 23]; | |
console.log('Lets start!'); | |
console.log(test_arr); | |
// get the odd numbers | |
console.log(combineLoop(test_arr, function (elm, idx) { | |
// console.log(idx, elm); | |
return elm % 2 === 0; | |
}, { | |
travType: 'continue', | |
})); | |
// all elements times 3 | |
console.log(combineLoop(test_arr, function (elm, idx, arr, resolve) { | |
// console.log(idx, elm); | |
resolve(elm * 3); | |
})); | |
// get elements, index from 9 to 2 | |
console.log(combineLoop(test_arr, function (elm, idx) { | |
// console.log(idx, elm); | |
}, { | |
loopStart: 9, | |
loopEnd: 2, | |
})); | |
// find the index of a number | |
var needIdx; | |
console.log(combineLoop(test_arr, function (elm, idx) { | |
return elm === 13 && !!(needIdx = idx); | |
}, { | |
travType: 'break', | |
}), needIdx, test_arr[needIdx]); | |
// selection sorting | |
var select_sort_arr = [9,8,48,13,46,18,7,34,0,18,9,3,40,7,58]; // Attention!! the array will be modified | |
console.log(combineLoop(select_sort_arr, function(elm, idx, arr, resolve) { | |
var tmp = elm, | |
sub = 0; // get the subscript of less value than curent | |
combineLoop(arr, function(e, i, a){ | |
if(tmp > e) { | |
sub = i; | |
tmp = e; | |
} | |
}, { | |
loopStart: idx + 1 | |
}); | |
arr[sub] = elm; | |
arr[idx] = tmp; | |
resolve(tmp); | |
})); | |
// bubble sorting | |
var bubble_sort_arr = [9,8,48,13,46,18,7,34,0,18,9,3,40,7,58]; // Attention!! the array will be modified | |
console.log(combineLoop(bubble_sort_arr, function(elm, idx, arr, resolve){ | |
var tmp = 0; | |
combineLoop(arr, function(e, i, a){ | |
if(a[i] > a[i+1]) { | |
tmp = a[i]; | |
a[i] = a[i+1]; | |
a[i+1] = tmp; | |
} | |
// console.log(i, tmp||a[i],a); | |
},{ | |
loopEnd: idx | |
}); | |
// console.log(idx,'/***clip***/', arr[idx]); | |
!idx || resolve(arr[idx]); | |
}, { | |
loopStart: bubble_sort_arr.length - 1, | |
loopEnd: -1 | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment