Extract x elements from the array (slice), but continue from the beginning if the end is reached

Let's say I have:

var array = [0,1,2,3,4,5,6,7,8,9] 

I define:

 var itemsToExtract = 5 var startindex = 7 var direction = "forward" 

I want to be able to do:

 array.someMethod(startindex, itemsToExtract, direction) 

and get

 [7,8,9,0,1] 

I also want it to work backwards if I set the direction back (slicing from right to left).

I was not too lazy and already tried something, see here: http://jsfiddle.net/MkNrr/

I am looking for something "more accurate", if there is, also there is a name for this method, is this a known problem?

Reference Information. I am trying to create a sequential image downloader (load one image (src) after another) for use in the image gallery. Maybe even such a library already exists?

+6
source share
6 answers

What about a function that returns front and back arrays? This way you do not need a switch. Something like that:

 function overslice(arr, idx, items) { var fwd = arr.filter(function(v,i){ return i >= idx }).slice(0, items), back = arr.filter(function(v,i){ return i <= idx }).slice(-items); while (fwd.length < items) { fwd = fwd.concat(arr).slice(0, items); } while (back.length < items) { back = arr.concat(back).slice(-items); } return { fwd: fwd, back: back }; } 

Then you can use it like:

 var array = [0,1,2,3,4,5,6,7,8,9] var result = overslice(array, 7, 5); console.log(result.fwd, result.back); //=> [7, 8, 9, 0, 1] [3, 4, 5, 6, 7] 
+1
source

My approach:

 function overslice(array, startindex, count, direction) { var retarray = []; var increment = (direction === 'backward') ? -1 : 1; for(var c=0, i = startindex; c<count; i+=increment, c++){ retarray.push(array[(i + array.length)%array.length]); } return retarray; } 

Working violin

UPDATE

Another version that uses the count variable to indicate direction using positive / negative values ​​and with a fix that allows the use of count longer than the length of the array:

 function overslice(array, startindex, count) { var retarray = []; var increment = (count >= 0) ? 1 : -1; count = Math.abs(count); for(var i = startindex, c = 0;c<count;i+=increment, c++){ if(i<0) i= array.length-1; retarray.push(array[i%array.length]); } return retarray; } 

Demo script

+1
source

Its a bit, but JS Bin looks fine:

 function overSlice(arr, start, count, dir){ if(dir==='backward'){ arr = arr.reverse(); start = arr.length-start-1; } var lastIndex = start+count; return arr.slice(start, lastIndex>arr.length?arr.length: lastIndex) .concat(arr.slice(0, lastIndex>arr.length?lastIndex-arr.length: 0)); } var arr = [0,1,2,3,4,5,6,7,8,9]; alert(overSlice(arr,7,5,'backward')); 
0
source

Just create a copy of the array and add the original array until it becomes long enough:

 var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] var start = 7 var count = 5 var tmparr = arr while (tmparr.length < start + count) { tmparr = tmparr.concat(arr); } var result = tmparr.slice(start, start + count); alert(result); 
0
source

To filter out invalid positions, I add some checks, without which the code can be even shorter.

 var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] var countToExtract = 10 var whereToBegin = -1 var direction = "backword" function overslice(array, startIndex, count, direction) { var retArray = []; var step = direction == "backword" ? -1 : 1; var startPos = (startIndex + array.length) % array.length; var endPos = (startPos + (count % array.length) * step + array.length) % array.length; for (var i = 0; i < count; i++) { var pos = (startPos + (i * step) % array.length + array.length) % array.length; retArray.push(array[pos]); } return retArray; } var lampa = overslice(arr, whereToBegin, countToExtract, direction) alert(lampa) 

with the code above, you can:
start from the negative position, which will be counted from the other end.
count may be longer than the length of the array, which will return your numbers repeatedly.

0
source

Hi, try this code.

 function myslice( ar , start , count , dir ) { dir = dir || 'F'; var out = [] , times = Math.ceil( ( start + count )/ ar.length ) + 1; while( times-- ) { [].push.apply( out, ar ); } if ( dir == 'B' ) { start = ar.length - start - 1; out = out.reverse() ; } return out.slice( start , start+count ); } myslice ( [0,1,2,3,4,5,6,7,8,9] , 7 , 5 , 'B' ); 
0
source

Source: https://habr.com/ru/post/950228/


All Articles