0

I created two buttons call next and prev. I also created an array like ['1','2'...'7']. It has a 7 number in the array. When I load it for the first time. It would show 1 2 3 4. How to show the next value of the array in the circular array like

Click next button > 2 3 4 5

Click next button > 3 4 5 6

Click next button > 4 5 6 7

Click next button > 5 6 7 1

Click prev button > 4 5 6 7

VLAZ
  • 18,437
  • 8
  • 35
  • 54
SuerTe_H
  • 55
  • 6
  • Does this answer your question? [Rotate the elements in an array in JavaScript](https://stackoverflow.com/questions/1985260/rotate-the-elements-in-an-array-in-javascript) – Llama Boy Sep 14 '20 at 07:28
  • 1
    post the snippets what you have done so far. – Azad Sep 14 '20 at 07:35

4 Answers4

2

Here's one way to do it:

// Elements
const array = [1, 2, 3, 4, 5, 6, 7];
// Size of elements to show
const count = 4;


let currentIndex = 0;
const show = step => {
  currentIndex += step;
  while(currentIndex < 0) {
    currentIndex += array.length;
  }  
  
  const result = Array.from({ length: count }, (_, i) => array[(currentIndex + i) % array.length]);
  
  console.log(result.join());
  return result;
}

show(0);
<button onclick="show(-1)">prev</button>
<button onclick="show(1)">next</button>
Hao Wu
  • 12,323
  • 4
  • 12
  • 39
  • 1
    This is the best answer to the flexibility it brings. Restrictions like preventing that the array loop over itself again could be done by implementing an interface on top of it. Here's an example: https://jsfiddle.net/nchepa7y/1/ Edit: One note with this example: Since the array is rebuilding you need to check the initial range in case if the array is smaller than the given count for the visual representation. – Jens Ingels Sep 14 '20 at 09:54
1

You could slice the array by having a look to the acural index position.

const
    getNext = (array, n = 4, start = 0) => () => {
        const index = start++;
        start %= array.length;
        return index + n <= array.length
            ? array.slice(index, index + n)
            : [...array.slice(index), ...array.slice(0, index - n + 1)];
    },
    array = [1, 2, 3, 4, 5, 6, 7],
    next = getNext(array);

console.log(...next());
console.log(...next());
console.log(...next());
console.log(...next());
console.log(...next());
console.log(...next());
console.log(...next());
console.log(...next());
console.log(...next());
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 323,592
  • 20
  • 270
  • 324
1

Okay, so what you want is a size of array as result (hence 4) and you have a range array (hence 1 - 7) . Basically no need to prepare the complete range array as input for processing, you can just have a count and can prepare the only block size resultant array as your requirement.

Array.from(Array(blockSize).keys(), a => ((a + count) % range) + 1)

This will do your job, here blockize is 4 and range is 7, only thing you need to manage is count throughout your program. It will start from 0 and you need to do +1 or -1 accordingly keeping your range in mind.

I am adding just a sample program to manage the count easily, however you can manage by your own way. and the good part is, you can go to 3-4 next step or previous in one go (as next or prev will go one positive or negative step)

Here is the wrapper of the solution just to manage count.

function buildBlock(range, blockSize) {
    let count = 0,
    getVal = () => Array.from(Array(blockSize).keys(), a => ((a + count) % range) + 1),
    context = {
        next: () => {count++; return getVal()},
        prev: () => {count = count -1 + range; return getVal()},
        current: getVal
    };
return context;
}

let block1 = buildBlock(7, 4);

console.log("Current: ", ...block1.current());
console.log("Next: ", ...block1.next());
console.log("Next: ", ...block1.next());
console.log("Next: ", ...block1.next());
console.log("Next: ", ...block1.next());
console.log("Next: ", ...block1.next());
console.log("Previous: ", ...block1.prev());
console.log("Previous: ", ...block1.prev());
console.log("Previous: ", ...block1.prev());
console.log("Previous: ", ...block1.prev());
console.log("Previous: ", ...block1.prev());
console.log("Previous: ", ...block1.prev());
console.log("Next: ", ...block1.next());
Koushik Chatterjee
  • 3,738
  • 3
  • 15
  • 29
1

Here's one:

//Globals
const data = [1, 2, 3, 4, 5, 6, 7];
const viewSize = 4;
let currentIndex = 0;
let [btnNext, btnPrev] = [null, null];

//Functions
const isIndexOuterEdge = (index, length, size) => index >= length - size;

const viewNumbers = (data, { startIndex = 0, size = viewSize } = {}) => {
  if(data == null || (size == null && viewSize == null)) return;
  else if(data.length < size) return data.join(' ');
  else return data.slice(startIndex, size + startIndex).join(' ');
}

const clickNext = (event) => {
  if(data == null, currentIndex == null || viewSize == null
  || isIndexOuterEdge(currentIndex, data.length, viewSize)) return;

  const index = currentIndex++ + 1;
  showOutput(index);
}
const clickPrevious = (event) => {
  if(currentIndex == null || currentIndex <= 0) return;

  const index = currentIndex-- - 1;
  showOutput(index);
}
const showOutput = (index) => {
  if(data == null || viewSize == null | viewSize == index || index < 0) return;

  //Print result
  const output = document.querySelector('#output');
  output.textContent = viewNumbers(data, {startIndex: index});

  //Disable button
  btnPrev.disabled = index <= 0;
  btnNext.disabled = isIndexOuterEdge(index, data.length, viewSize);
}

//Setup
const setup = () => {
  //Bind Targets
  btnNext = document.querySelector('#btn_next'),
  btnPrev = document.querySelector('#btn_prev')

  //Bind Events

  btnNext.addEventListener('click', clickNext);
  btnPrev.addEventListener('click', clickPrevious);

  //Init
  showOutput(currentIndex);
}


//Load
window.addEventListener('load', setup);
<button id="btn_prev">
  Prev
</button>
<button id="btn_next">
  Next
</button>
<div id="output"></div>
Jens Ingels
  • 788
  • 1
  • 6
  • 10