I'm currently developing a circular carousel feature. With an array of n items, where n is greater than 6 in my current scenario, I need to identify all items within the array that are either less than or equal to 3 positions away from a specific index (currentIndex) in a circular manner:
// currentIndex = 0
// i 0 1 2 3 4 5 6 7 8 9
// --------------------------------------------------------
// offset 0 +1 +2 +3 +3 +3 +3 -3 -2 -1
Using the example above, with 0 as the currentIndex, indices 1, 2, and 3 are within 3 places of currentIndex. Similarly, indices 7, 8, and 9 are also within 3 positions in a circular fashion relative to currentIndex. Any other indices outside this range are considered to be at a value of 3. These positive and negative values will later correspond to positions on the screen.
To calculate the offset position of a given index in relation to the currentIndex, I've implemented the following function:
function getOffset(currentIndex: number, index: number, length: number) {
const diff = index - currentIndex;
if (diff === 0) {
return 0;
} else if (diff < 0) {
if (diff < -3) {
return Math.min(length - currentIndex + index, 3);
} else {
return Math.min(diff, 3);
}
} else {
if (diff < length - 3) {
return Math.min(diff, 3);
} else {
return Math.max(diff - length, -3);
}
}
}
// getOffset(0, 0, 10) -> 0
// getOffset(0, 1, 10) -> 1
// getOffset(0, 9, 10) -> -1
// getOffset(0, 6, 10) -> 3
The algorithm functions correctly but may seem verbose. Is there a more streamlined approach to achieve the same outcome?