Перемещение по отрезку
У меня есть отрезок от i1 до i2
Мне нужно научится перемещатся по этому отрезку по кругу.
Если от 0 до 10 отрезок, я стою на индексе 2 и сдвинусь на -3, то окажусь на 10 индексе
Если сдвинусь на -14, то окажусь на 10 индексе

Также я могу двигаться и в правую сторону.
/**
* Функция для сдвига индекса
* @param {number} length - Длина элементов
* @param {number} index - Индекс текущего элемента
* @param {number} shift - Сдвиг
*/
function shiftDigit(length, index, shift) {
const indexSumShift = index + shift;
if (indexSumShift < 0) {
return length + indexSumShift;
}
return (index + shift) % length;
}
console.log(shiftDigit(11, 3, -5));
Мой код не имеет особого смысла, потому что я запутался
UPD: Я подумал, правильнее будет ещё указать, с какого значения индекс отрезка начинается и где заканчивается:
/**
* Функция для сдвига индекса
* @param {number} start - Начало отрезка
* @param {number} end - Конец отрезка
* @param {number} index - Индекс текущего элемента
* @param {number} shift - Сдвиг
*/
function shiftDigit(start, end, index, shift) {
}
console.log(shiftDigit(0, 10, 3, -15));
Ответы (2 шт):
Приводим диапазон к 0..size-1.
Прибавляем сдвиг. Если результат отрицательный, то после взятия модуля он лежит в диапазоне -size..-1, приводим его к положительному добавлением size.
Второй раз берём модуль на случай, если результат был положительный.
Приводим обратно к start...end
function shiftDigit(start, end, index, shift) {
let size = end - start + 1;
return start + ((index - start + shift) % size + size) % size;
}
console.log(shiftDigit(0, 10, 3, -15));
console.log(shiftDigit(0, 10, 3, 15));
смотреть метод doShift. Все остальное для визуализации
const app = new Vue({
el: '#app',
data() {
return {
length: 5,
activeIndex: 2,
multi: 2
}
},
methods: {
doShift(active, shift, length) {
const z = (active + shift) % length
this.activeIndex = z < 0 ? length + z : z
}
},
});
.index {
padding: 10px;
width: 20px;
display: flex;
justify-content: center;
align-items: center;
margin: 5px;
border: 1px solid;
}
.control {
padding: 8px;
margin: 4px;
cursor: pointer;
}
.active {
background-color: red;
}
.wrap {
display: flex;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<div id="app">
<div class="wrap">
<div v-for="i in length" class="index" :class="activeIndex === i-1 ? 'active' : ''">{{i-1}}</div>
</div>
<button v-for="i in length" class="control" @click="doShift(activeIndex, i*multi, length)">+{{i*multi}}</button>
<button v-for="i in length" class="control" @click="doShift(activeIndex, +('-' +i*multi), length)">-{{i*multi}}</button>
</div>