Как рандомизировать (перемешать) массив JavaScript?
У меня есть такой массив:
var arr1 = ["a", "b", "c", "d"];
Как я могу рандомизировать / перемешать это?
74 ответа
Я не мог найти тот, который мне нравился. Вот решение, которое я придумал. Я не использовал слишком много бессмысленных переменных, так как сейчас я кодирую именно так.
Array.prototype.shuffle = function() {
for (let i in this) {
if (this.hasOwnProperty(i)) {
let index = Math.floor(Math.random() * i);
[
this[i],
this[index]
] = [
this[index],
this[i]
];
}
}
return this;
}
Я надеюсь, что это поможет тем из вас, кто, возможно, не очень хорошо это понимает.
const arr = [
{ index: 0, value: "0" },
{ index: 1, value: "1" },
{ index: 2, value: "2" },
{ index: 3, value: "3" },
];
let shuffle = (arr) => {
let set = new Set();
while (set.size != arr.length) {
let rand = Math.floor(Math.random() * arr.length);
set.add(arr[rand]);
}
console.log(set);
};
shuffle(arr);
Я написал функцию случайного воспроизведения самостоятельно. Разница здесь в том, что он никогда не будет повторять значение (проверяет код для этого):
function shuffleArray(array) {
var newArray = [];
for (var i = 0; i < array.length; i++) {
newArray.push(-1);
}
for (var j = 0; j < array.length; j++) {
var id = Math.floor((Math.random() * array.length));
while (newArray[id] !== -1) {
id = Math.floor((Math.random() * array.length));
}
newArray.splice(id, 1, array[j]);
}
return newArray; }
Перемешать массив строк:
shuffle = (array) => {
let counter = array.length, temp, index;
while ( counter > 0 ) {
index = Math.floor( Math.random() * counter );
counter--;
temp = array[ counter ];
array[ counter ] = array[ index ];
array[ index ] = temp;
}
return array;
}
Перетасовка массива с использованием рекурсии JS.
Не лучшая реализация, но она рекурсивна и уважает неизменность.
const randomizer = (array, output = []) => {
const arrayCopy = [...array];
if (arrayCopy.length > 0) {
const idx = Math.floor(Math.random() * arrayCopy.length);
const select = arrayCopy.splice(idx, 1);
output.push(select[0]);
randomizer(arrayCopy, output);
}
return output;
};
Быстрое и красивое решение (возможно, не самое эффективное)
const data = [1, 2, 3, 4, 5, 6];
const randomizedData = data
.map(d => ({r: Math.random(), d}))
.sort((a, b) => a.r - b.r)
.map(d => d.d);
console.log(randomizedData);
Хочу поделиться одним из миллиона способов решения этой проблемы =)
function shuffleArray(array = ["banana", "ovo", "salsicha", "goiaba", "chocolate"]) {
const newArray = [];
let number = Math.floor(Math.random() * array.length);
let count = 1;
newArray.push(array[number]);
while (count < array.length) {
const newNumber = Math.floor(Math.random() * array.length);
if (!newArray.includes(array[newNumber])) {
count++;
number = newNumber;
newArray.push(array[number]);
}
}
return newArray;
}
здесь с простым циклом while
function ShuffleColor(originalArray) {
let shuffeledNumbers = [];
while (shuffeledNumbers.length <= originalArray.length) {
for (let _ of originalArray) {
const randomNumb = Math.floor(Math.random() * originalArray.length);
if (!shuffeledNumbers.includes(originalArray[randomNumb])) {
shuffeledNumbers.push(originalArray[randomNumb]);
}
}
if (shuffeledNumbers.length === originalArray.length)
break;
}
return shuffeledNumbers;
}
const colors = [
'#000000',
'#2B8EAD',
'#333333',
'#6F98A8',
'#BFBFBF',
'#2F454E'
]
ShuffleColor(colors)
//doesn change array
Array.prototype.shuffle = function () {
let res = [];
let copy = [...this];
while (copy.length > 0) {
let index = Math.floor(Math.random() * copy.length);
res.push(copy[index]);
copy.splice(index, 1);
}
return res;
};
let a=[1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(a.shuffle());
Используя метод сортировки и математический метод:
var arr = ["HORSE", "TIGER", "DOG", "CAT"];
function shuffleArray(arr){
return arr.sort( () => Math.floor(Math.random() * Math.floor(3)) - 1)
}
// every time it gives random sequence
shuffleArr(arr);
// ["DOG", "CAT", "TIGER", "HORSE"]
// ["HORSE", "TIGER", "CAT", "DOG"]
// ["TIGER", "HORSE", "CAT", "DOG"]
$=(m)=>console.log(m);
//----add this method to Array class
Array.prototype.shuffle=function(){
return this.sort(()=>.5 - Math.random());
};
$([1,65,87,45,101,33,9].shuffle());
$([1,65,87,45,101,33,9].shuffle());
$([1,65,87,45,101,33,9].shuffle());
$([1,65,87,45,101,33,9].shuffle());
$([1,65,87,45,101,33,9].shuffle());
Сообщество говорит arr.sort((a, b) => 0.5 - Math.random())
не на 100% случайный!
да! Протестировал и рекомендую не использовать этот метод!
let arr = [1, 2, 3, 4, 5, 6]
arr.sort((a, b) => 0.5 - Math.random());
Но я не уверен. Итак, я пишу код для тестирования!... Вы также можете попробовать! Если вы достаточно заинтересованы!
let data_base = [];
for (let i = 1; i <= 100; i++) { // push 100 time new rendom arr to data_base!
data_base.push(
[1, 2, 3, 4, 5, 6].sort((a, b) => {
return Math.random() - 0.5; // used community banned method! :-)
})
);
} // console.log(data_base); // if you want to see data!
let analysis = {};
for (let i = 1; i <= 6; i++) {
analysis[i] = Array(6).fill(0);
}
for (let num = 0; num < 6; num++) {
for (let i = 1; i <= 100; i++) {
let plus = data_base[i - 1][num];
analysis[`${num + 1}`][plus-1]++;
}
}
console.log(analysis); // analysed result
В 100 различных случайных массивах. (мой проанализированный результат)
{ player> 1 2 3 4 5 6
'1': [ 36, 12, 17, 16, 9, 10 ],
'2': [ 15, 36, 12, 18, 7, 12 ],
'3': [ 11, 8, 22, 19, 17, 23 ],
'4': [ 9, 14, 19, 18, 22, 18 ],
'5': [ 12, 19, 15, 18, 23, 13 ],
'6': [ 17, 11, 15, 11, 22, 24 ]
}
// player 1 got > 1(36 times),2(15 times),...,6(17 times)
// ...
// ...
// player 6 got > 1(10 times),2(12 times),...,6(24 times)
Как видите, это не так уж и много случайностей! так...
не используйте этот метод!
Если вы протестируете несколько раз, то увидите, что игрок 1 получил (номер 1) столько раз!
и игрок 6 получил (номер 6) в большинстве случаев!
Функциональное решение с использованием Ramda.
const {map, compose, sortBy, prop} = require('ramda')
const shuffle = compose(
map(prop('v')),
sortBy(prop('i')),
map(v => ({v, i: Math.random()}))
)
shuffle([1,2,3,4,5,6,7])