Если первый и последний элементы массива всегда остаются в одном и том же месте, вы можете применить обычный алгоритм перетасовки, такой как современный вариант Фишера и Йетса , пропуская эти позиции:
function customShuffle(arr) {
if (arr.length < 3) {
return arr;
}
// Note the -2 (instead of -1) and the i > 1 (instead of i > 0):
for (let i = arr.length - 2; i > 1; --i) {
const j = 1 + Math.floor(Math.random() * i);
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
console.log(customShuffle([1, 2, 3, 4, 5]).join(', '));
console.log(customShuffle(['A', 'B', 'C', 'D', 'E']).join(', '));
.as-console-wrapper {
max-height: 100vh;
}
В противном случае, если вы хотите выбрать первый и последний элементы, как вы указали в исходном вопросе, вы можете сделать что-то вроде этого:
- Найдите индекс элементов, которые вы хотите иметь в первой и последней позициях:
firstIndex
и lastIndex
. - Если эти элементы существуют (они могут отсутствовать),удалите их из массива.
- Примените алгоритм перемешивания к оставшимся элементам (нет необходимости также перемешивать
first
и last
). - Добавьте первый и последний элементы обратно вих место, если вам нужно.
function customShuffle(arr, first, last) {
// Find and remove first and last:
const firstIndex = arr.indexOf(first);
if (firstIndex !== -1) arr.splice(firstIndex, 1);
const lastIndex = arr.indexOf(last);
if (lastIndex !== -1) arr.splice(lastIndex, 1);
// Normal shuffle with the remainign elements using ES6:
for (let i = arr.length - 1; i > 0; --i) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
// Add them back in their new position:
if (firstIndex !== -1) arr.unshift(first);
if (lastIndex !== -1) arr.push(last);
return arr;
}
console.log(customShuffle([1, 2, 3, 4, 5], 5, 1).join(', '));
console.log(customShuffle(['A', 'B', 'C', 'D', 'E'], 'E', 'C').join(', '));
console.log(customShuffle([1, 2, 3, 4, 5], 10, 20).join(', '));
.as-console-wrapper {
max-height: 100vh;
}