JavaScript에서 배열 요소의 순서를 무작위로 섞고 싶다면 피셔-예이츠(Fisher-Yates) 셔플 알고리즘을 사용하는 것이 가장 좋습니다. 이 방법은 배열의 끝에서부터 시작해 매번 남은 요소 중 하나를 임의로 선택한 뒤 현재 위치의 값과 교환하는 방식으로, 모든 순열이 거의 동일한 확률로 나타나도록 보장합니다.
예제
<html>
<body>
<script>
function randomFunc(myArr) {
var l = myArr.length, temp, index;
while (l > 0) {
index = Math.floor(Math.random() * l); // 0 ~ l-1 사이의 임의의 인덱스
l--;
temp = myArr[l];
myArr[l] = myArr[index];
myArr[index] = temp;
}
return myArr;
}
var arr = [10, 20, 30, 40, 50];
document.write(randomFunc(arr));
</script>
</body>
</html>
출력 결과
20,50,40,30,10
참고: Math.random()은 실행할 때마다 다른 값을 반환하기 때문에 위 결과는 어디까지나 예시입니다. 실제로 실행할 때마다 출력되는 순서는 계속 달라집니다.
코드 작동 원리
myArr.length로 배열의 길이를 구해 변수l에 저장합니다.Math.random() * l에Math.floor()를 적용해 0부터 l-1 사이의 정수 인덱스를 얻습니다.- 현재 마지막 위치(
l)의 요소와 임의로 선택한 인덱스(index)의 요소를 임시 변수temp를 이용해 서로 교환합니다. l을 1씩 감소시키며 배열의 앞쪽으로 이동하고,l이 0이 되면 반복을 종료한 뒤 섞인 배열을 반환합니다.
알아두면 좋은 핵심 포인트
- 피셔-예이츠 셔플은 O(n)의 시간 복잡도로 배열 전체를 효율적으로 섞을 수 있습니다.
- 원본 배열을 직접 변경(in-place)하므로, 원본을 유지해야 한다면
[...arr]처럼 복사본을 만들어 사용하는 것이 안전합니다. sort(() => Math.random() - 0.5)방식으로도 섞을 수 있지만 결과에 편향(bias)이 생길 수 있어 실무에서는 권장되지 않습니다.