Skip to content

Instantly share code, notes, and snippets.

@uolcano
Created July 28, 2016 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uolcano/c13abf236321ce344ee5a4585145c05b to your computer and use it in GitHub Desktop.
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]
/***************************************************************************************************
* @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