본문 바로가기
웹 개발/javascript

underbar shuffle 메소드

by 스토리라이언 2021. 2. 22.

shuffle을 사전에 찾아보니 다음과 같이 정의하고 있다.

rearrange (a deck of cards) by sliding the cards over each other quickly.

즉 카드를 다른 카드 위에 섞으면서 재정렬하는 것이다. 

 

_shuffle 은 배열 요소의 순서가 랜덤하게 변경된 새로운 배열을 리턴한다.

예를 들면 음악이나 비디오를 재생할 때 랜덤으로 재생할 때 사용할 수 있다. 

본격적인 shuffle 메소드 코드를 작성하기 전에 먼저 정리할 것이 있다. 

 

Math. random() 

Math.random() 함수는 0 ~ 1 사이 부동수숫점 의사난수를 반환한다. 즉 0에서 0.9999...까지 랜덤한 수를 생성한다. 

정수인 난수를 생성하고 싶다면 수를 내림하는 Math.floor의 인자값으로 Math.random()와 범위의 곱을 넣어주면 된다. 

Math.floor(Math.random() * (범위);

 

이제 shuffle underbar 메소드 코드를 살펴보도록 하자. 

_.shuffle = function (arr) { 
/*arr = [ 'a', 'b', 'c', 'd', 'e']; 인 경우를 생각해 보자. 
//arr.slice()는 어떤 배열의 begin부터 end까지 shallow copy로 새로운 배열 객체로 반환한다. 
slice()로 안의 인자가 없는 경우는 arr.length 를 추출한다. 
*/
  let arrCloned = arr.slice(); // arrCloned에 ["a", "b", "c", "d", "e"] 값이 들어가 있다. 
  for (let fromIdx = 0; fromIdx < arr.length; fromIdx++) {
  
  //[1. 반복문을 돌면서 요소를 랜덤하게 정수값으로 선택한다. ]
    /* Math.floor(Math.random() * arr.length)의 의미는 
    입력받은 배열의 수를 정수값으로 랜덤하게 리턴하는 식이다. 
    
    */
    const toIdx = Math.floor(Math.random() * arr.length);//임의 정수값이 toIdx에 할당된다. 
    /* 
    Math.floor(Math.random()*5);  -> 1-4까지 랜덤하게 정수 생성
    Math.floor(Math.random()*10); -> 1-9까지 램덤하게 정수 생성
    Math.floor(Math.random()*77); -> 1-76, 즉 1부터 arr.length-1까지의 랜덤한 정수값이 toIdx에 할당
    */
    
  //[2. 아래 3개의 코드는 뽑은 랜덤 정수값 요소를 뒤섞어 원래 배열 arrCloned에 할당]
  
  let temp = arrCloned[fromIdx];
    /* 2-1 arrCloned[fromIdx]: for반복문을 돌면서 0부터 배열의 개수만큼의 배열이 새로운 배열 temp에 할당된다. 
  fromIdx = 0 -> arrCloned[0] === 'a'
  fromIdx = 1 -> arrCloned[1] === 'b'
  fromIdx = 2 -> arrCloned[2] === 'c'
  fromIdx = 3 -> arrCloned[3] === 'd'
  fromIdx = 4 -> arrCloned[4] === 'e'
 의 값이 temp에 할당
     */
    
    arrCloned[fromIdx] = arrCloned[toIdx];
  /* 2-2. arrCloned[toIdx]: arr.length가 5인 경우 toIdx 에 0,1,2,3,4 의 수 중 임의의 수가 할당.
  -> arrCloned[toIdx] === arrCloned[4] 을 arrCloned[fromIdx] 값에 재할당한다. 
   */
    
    arrCloned[toIdx] = temp;
  /* 2-3. 
   이미 temp안에는  'a', 'b', 'c', 'd', 'e' 가 순서있게 들어 있다. 
   이것을 arrCloned[toIdx]에 할당한다는 말은 ["e", "a", "c", "d", "b"]로 재배열될 수 있다.
   다시 말해 원래는 arrCloned에는
   0: "a"
   1: "b"
   2: "c"
   3: "d"
   4: "e"
    ->
    0: "e"
    1: "a"
    2: "b"
    3: "c"
    4: "d"
  이런 식으로 바뀔 수 있다는 것이다. 랜덤이기에 이것은 
    0: "b"
    1: "e"
    2: "c"
    3: "a"
    4: "d"
  이렇게도 바뀔 수 있다는 말이다. 
  */
    
  }
  return arrCloned;//arrCloned하면 예를 들면 ["e", "a", "c", "d", "b"] 리턴된다. 
};

위의 코드를 콘솔로 확인해 보면 다음과 같다,

Shuffle([ 'a', 'b', 'c', 'd', 'e']) 
(5) ["e", "d", "c", "a", "b"]

Shuffle(['a', 'b', 'c', 'd', 'e'])
(5) ["b", "e", "c", "a", "d"]

Shuffle(['a', 'b', 'c', 'd', 'e'])
(5) ["c", "e", "d", "b", "a"]

Shuffle(['a', 'b', 'c', 'd', 'e'])
(5) ["c", "e", "a", "b", "d"]

함수를 호출할 때마다 배열이 랜덤으로 재배열되는 것을 확인할 수 있다. 

댓글