1

Need a function which return next N elements from given array, with given offset, but when offset larger then array length, it must return elements at the beginning of array.

Interface:
slice2(array, chunk, offset);

Examples:

var array = [1,2,3,4,5];
slice2(array,2,2) Output: [3,4]
slice2(array,2,4) Output: [5,1]
slice2(array,3,4) Output: [5,1,2]

0

7 Answers 7

9
function slice2(array, chunk, offset) {
    var subarray = [];
    for (var i = 0; i<chunk; i++) {
        var ind = (offset + i) % array.length;
        subarray.push(array[ind]);
    }

    return subarray;
}
Sign up to request clarification or add additional context in comments.

4 Comments

You don't need to manually loop through the array and push each variable individually. Especially on larger arrays, I'd suggest using javascript's native functionality for (sub-)array manipulation.
If chunk happens to be more than array length this function will insert the same element multiple times into the result.
@Bruno, good notion, and you are absolutely right, however I don't think this is an incorrect behavior. The question states that the function should be able to "go around" an array, but said nothing about how many times it should be able to do this. On the other hand, this is just a prototype of how the problem can be solved. It can be easily adjusted for specific needs.
@Andrei Agree. In fact I thought it was an ingenious way of solving this problem and my comment is probably easily fixed by return whole array if chunk >= length of array.
0

The buillt-in .slice() method may be enough for your problem :

var slice = array.slice(1,3);

I set-up a quick jsfiddle, the interface would need change since it only allows a rance

1 Comment

But .slice() doesn't wrap around to the beginning of the array if you try to get elements past the end...
0

Try this:

function slice2(array, chunk, offset){
    var end = offset + chunk,
        out = array.slice(offset, end);  // Get the chunk
    if(array.length < end){              // If the chunk should wrap
        out = out.concat(array.slice(0, end - array.length)); // Concatenate a the rest of the chunk, from the start of the array, to the output.
    }
    return out;
}

It doesn't manually loop through the array, and uses a bare minimal of calculations.

4 Comments

if the chunk wanted is longer than the end of the array, it will populate with the beginning of the array again. ie. [1,2,3,4,5] wanting chunk length of 3 and the offset is 4 will produce [4,5,1]
@AndrewKillen: Yea, that was what this question was asking for...
@Cerbus, apologies, I did not read the question fully, just the chunked needs, and gave your code in whirl to see how well it worked. Obviously you don't get 64k clout without the skills to back it up ;)
Hehe that's okay, @AndrewKillen :D That said, this answer was pretty early days for me.
0

Sorry couldn't help myself :)

The following function handles a few more scenarios and does this with only 2 slices.

// standard
slice2( [1,2,3,4,5], 3, 3 ); // [1, 4, 5]
// specify chunk as a negative number
slice2( [1,2,3,4,5], -3, 3 ); // [1, 2, 3]
// what if chunk is larger than array
slice2( [1,2,3,4,5], -7, 3 ); // [1, 2, 3, 4, 5]
// what if chunk is 0
slice2( [1,2,3,4,5], 0, 3 ); // []


function slice2( array, chunk, offset ) {

    var start1, len = array.length, end1, start2, end2, result;

    if( !chunk || !array ) return []; // if chunk or array resolve to falsy value.
    if( Math.abs(chunk) >= len ) return array;

    if( chunk < 0 ) {

        end1 = offset;
        leftover = offset + chunk;
        start1 = leftover < 0 ? 0 : leftover;
        start2 = leftover;
        end2 = len;

    } else {

        start1 = offset;
        leftover = ( offset + chunk ) - len;
        end1 = leftover > 0 ? ( offset + chunk ) : len;
        start2 = 0;
        end2 = leftover;
    }

    result = array.slice( start1, end1 );
    if( leftover ) result = array.slice( start2, end2  ).concat( result );

    return result;
}

Fiddle here

Comments

0

Here is a snippet of what I did. Credits to @Andrei I just modified his code. So what I wanted was a function to get the selected number in an array and x numbers before and x numbers after that number. Eg, [1,2,3,4,5,6,7,8] if I select 2 as my offset and chunk as 3, output would be: [ 8, 1 , 2, 3, 4, 5, 6 ] If offset = 3, chunk = 3, op: [ 1, 2, 3, 4, 5, 6, 7]

function cyclicSlice(array, chunk, offset) {
var subarray = [];
for (var i = array.length; i>=(array.length-chunk); i--) {
    var ind = (offset + i) % array.length;
    subarray.push(array[ind]);
}
subarray = subarray.reverse();
const newOffset = offset + 1; // To avoid the repititon of the selected number
for (var i = 0; i<chunk; i++) {
    var ind = ( newOffset + i) % array.length;
    subarray.push(array[ind]);
}

return subarray;

}

Comments

0
function sleepPromise(durationInMs) {
  return new Promise((resolve) => {
    setTimeout(resolve, durationInMs);
  })
}

function getNextChunk(array, chunkSize, indexDoneUpto) {
  let nextChunk = []
  let arrayLength = array.length
  if (chunkSize > arrayLength) chunkSize = arrayLength
  for (let i = 0; i < chunkSize; i++) {
    nextChunk.push(array[indexDoneUpto])
    indexDoneUpto++
    if (indexDoneUpto > (arrayLength - 1)) {
      indexDoneUpto = 0
    }
  }
  return { nextChunk, indexDoneUpto }
}

let array1 = [1, 2, 3, 4, 5, 6, 7, 8]

let chunkSize = 3
let indexDoneUpto = 0

while (true) {
  let result = getNextChunk(array1, chunkSize, indexDoneUpto)
  indexDoneUpto = result.indexDoneUpto
  console.log(result.nextChunk)
  await sleepPromise(500)
}

will output:

[ 1, 2, 3 ]
[ 4, 5, 6 ]
[ 7, 8, 1 ]
[ 2, 3, 4 ]
[ 5, 6, 7 ]
[ 8, 1, 2 ]
[ 3, 4, 5 ]
[ 6, 7, 8 ]
[ 1, 2, 3 ]
[ 4, 5, 6 ]
[ 7, 8, 1 ]
...

Comments

-1

private static List sliceArray(List mainarray, int chunk, int offset) {

    int size = mainarray.size();
    List<Integer> resultArray = new ArrayList<Integer>();

    if(!mainarray.contains(chunk)){
        return null;
    }

    int index = mainarray.indexOf(chunk);
    int doOffset = size - index;

    if(doOffset > offset){

        for(int element = 1 ; element <= offset; element++ ){
            resultArray.add(mainarray.get(index+1));
            index++;
        }

    }else if(doOffset == 0){
        for(int element = 0 ; element <= offset; element++ ){
            element = mainarray.get(element);
            resultArray.add(element);
        }

    }else{
        int position =0;
        for(int element = index ; element <= offset; element++ ){
            int value = 0;
            if(element < size-1){
                value = mainarray.get(element+1);
            }
            else
            {
                value = mainarray.get(position);
                position ++;
            }
            resultArray.add(value);
        }
    }

    return resultArray;
    // TODO Auto-generated method stub

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.