Answered
How can I take a given array of strings and randomly shuffle the index positions of each string?
For example, an array of strings like this:
["string1", "string2", "string3", "string4", "string5"]
Should be randomly shuffled into this:
["string3", "string5", "string1", "string4", "string2"]
Here's a function you can use. It's based on the Fisher-Yates (aka Knuth) Shuffle.
const shuffle = function(array) {
let currentIndex = array.length, randomIndex;
// Only run while there are still items to shuffle
while (currentIndex != 0) {
// Pick a remaining element
randomIndex = Math.floor(Math.random() * currentIndex);
// Decrement the currentIndex value
currentIndex--;
// Swap it with the current element
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
}
return array;
}
It's used like this:
shuffle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
// [10, 1, 8, 6, 3, 2, 4, 7, 9, 5]
You can do this using a combination of map()
and sort()
:
const originalArray = ["string1", "string2", "string3", "string4", "string5"]
const shuffledArray = originalArray
.map(value => ({ value, sort: Math.random() }))
.sort((a, b) => a.sort - b.sort)
.map(({ value }) => value)
sort
key.This is a good method for short to medium length arrays. If you are dealing with large arrays, this method may not be optimal in terms of performance.
This is an implementation of the Schwartzian Transform.
The Underscore library has the shuffle method:
_.shuffle(["string1", "string2", "string3", "string4", "string5"])
This will shuffle your array in place and return the new array. It uses the Fisher-Yates (aka Knuth) Shuffle method.
Durstenfeld Shuffle method for you:
function shuffleArray(arr) {
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]];
}
return arr
}
shuffleArray(["string1", "string2", "string3", "string4", "string5"])
// [ "string5", "string3", "string2", "string4", "string1" ]
It picks a random item from the array and removes it from the next draw. Much like picking a random card from a deck cards would work.
function shuffle(array) {
let count = array.length, randomnumber, temp;
while (count){
randomnumber = Math.random() * count-- | 0;
temp = array[count];
array[count] = array[randomnumber];
array[randomnumber] = temp
}
return array
}
Another function you could use:
function shuffle(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array
}
It's an implementation of the Durstenfeld Shuffle.
Here's a recursive solution that should work for you:
const shuffleArray = (array) => {
if (array.length === 1) return array;
const randomNum = Math.floor(Math.random() * array.length);
return [array[randomNum], ...shuffleArray(array.filter((_, i) => i != randomNum))];
};
function shuffle(array) {
return [...array].map((_, i, newArray) => {
var random = i + (Math.floor( Math.random() * (newArray.length - i)));
[newArray[random], newArray[i]] = [newArray[i], newArray[random]]
return newArray[i]
})
}