Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript 배열을 무작위로 섞는(셔플) 방법 완벽 가이드

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()은 실행할 때마다 다른 값을 반환하기 때문에 위 결과는 어디까지나 예시입니다. 실제로 실행할 때마다 출력되는 순서는 계속 달라집니다.

코드 작동 원리

  1. myArr.length로 배열의 길이를 구해 변수 l에 저장합니다.
  2. Math.random() * lMath.floor()를 적용해 0부터 l-1 사이의 정수 인덱스를 얻습니다.
  3. 현재 마지막 위치(l)의 요소와 임의로 선택한 인덱스(index)의 요소를 임시 변수 temp를 이용해 서로 교환합니다.
  4. l을 1씩 감소시키며 배열의 앞쪽으로 이동하고, l이 0이 되면 반복을 종료한 뒤 섞인 배열을 반환합니다.

알아두면 좋은 핵심 포인트

  • 피셔-예이츠 셔플은 O(n)의 시간 복잡도로 배열 전체를 효율적으로 섞을 수 있습니다.
  • 원본 배열을 직접 변경(in-place)하므로, 원본을 유지해야 한다면 [...arr]처럼 복사본을 만들어 사용하는 것이 안전합니다.
  • sort(() => Math.random() - 0.5) 방식으로도 섞을 수 있지만 결과에 편향(bias)이 생길 수 있어 실무에서는 권장되지 않습니다.