[JavaScript] 특정 숫자 범위에서 중복을 제외한 랜덤 숫자 뽑는 방법

이은진·2020년 11월 29일
3

JavaScript Study

목록 보기
16/24

사용자 정보를 담은 mock data를 만들고 화면에 랜덤으로 출력하는 코드를 짜게 되었다. 이전까지는 랜덤 데이터 또는 랜덤 숫자를 1개씩만 출력하면 되었기 때문에 하지 않아도 될 고민을 지금 하게 되었다. 랜덤 배열 중 여러 개를 뽑되, 그 여러 개에 중복되는 데이터가 없도록 만들고 싶었다.

1. 특정한 범위 내에서 단순히 랜덤한 숫자 한 개를 뽑는 방법

Math.random() 메서드는 0부터 1미만의 난수를 출력하고, Math.floor() 메서드는 괄호 안의 숫자를 내림해주는 역할을 한다. 0부터 49까지의 랜덤한 정수를 출력하기 위해서는 Math.random() * 50 메서드로 먼저 0부터 50 미만까지의 난수를 출력하도록 한 후, 이를 Math.floor()로 감싸 0부터 49까지의 정수를 출력하도록 한다.

//0부터 49까지의 랜덤 정수 1개 출력하는 방법
const randomNumber = Math.floor(Math.random() * 50)
console.log(randomNumber) // 37

여기서 조금 더 나아가서 10부터 59까지의 정수를 출력하고 싶다면 Math.random()으로 구한 랜덤 수에 10을 더해주면 된다.

//0부터 49까지의 랜덤 정수 1개 출력하는 방법
const randomNumber = Math.floor(Math.random() * 50 + 10)
console.log(randomNumber) // 53

2. 특정한 범위 내에서 중복을 제외한 숫자 여러 개를 뽑는 방법

중복을 제외한 숫자를 뽑는 방법은 로또 뽑기 알고리즘을 참고해서 만들어보았다. 내가 필요한 것은 mock data 배열의 총 인덱스 개수(totalIndex)와, 뽑고자 하는 원소의 개수(selectingNumber)를 각각 넣으면 중복을 제외한 인덱스 값이 배열로(randomIndexArray) 출력되는 것이었다.

먼저, 출력하고자 하는 배열을 빈 배열로 일단 만들어서 선언해준다. 그리고 랜덤 숫자를 만드는 Math.floor(Math.random() * max) 를 이용해 for문으로 필요한 숫자 갯수만큼 돌면서 randomIndexArray에 넣어준다.

//24개의 배열 요소들 중, 7번의 랜덤한 숫자 뽑기를 하는 코드
let randomIndexArray = []
for (i=0; i<7; i++) {
  randomNum = Math.floor(Math.random() * 24)
  randomIndexArray.push(randomNum)
}
console.log(randomIndexArray)

// [3, 12, 12 ,2, 21, 18, 9]

그런데 우리는 중복을 피해야 하기 때문에, for문을 돌 때마다 지금 뽑은 숫자가 이미 randomIndexArray에 들어 있는지 확인하고, 없으면 넣어주는 코드를 추가해야 한다.

//중복을 제외하고 7회 돌면서 랜덤 숫자 뽑기
let randomIndexArray = []
for (i=0; i<7; i++) {
  randomNum = Math.floor(Math.random() * 24)
  if (randomIndexArray.indexOf(randomNum) === -1) {
    randomIndexArray.push(randomNum)
  }
}
console.log(randomIndexArray)
// [12, 2, 6, 23, 8, 15]

그런데 여기서 문제가 또 생긴다. 이미 뽑은 숫자인지 확인했을 때 이미 들어있는 숫자와 겹치는 경우 그냥 숫자를 안 뽑고 그 턴을 지나가는 셈이기 때문에, 7개의 숫자를 뽑고 싶은데 5개, 6개만 출력되는 문제가 생겼다. 따라서 이미 뽑은 숫자일 경우, i를 1씩 감소시켜 다시 그 턴을 돌도록 코드를 추가했다.

//중복을 제외하고 7개의 랜덤 숫자 뽑기
let randomIndexArray = []
for (i=0; i<7; i++) {
  randomNum = Math.floor(Math.random() * 24)
  if (randomIndexArray.indexOf(randomNum) === -1) {
    randomIndexArray.push(randomNum)
  } else {
    i--
  }
}
console.log(randomIndexArray)
// [0, 15, 22, 13, 1,  2,  3]

이렇게 해서, 최대 범위와 필요한 랜덤 숫자 개수를 넣으면 필요한 랜덤 숫자가 배열로 출력되는 함수를 완성했다.

//selecting random index without same element
const selectIndex = (totalIndex, selectingNumber) => {
  let randomIndexArray = []
  for (i=0; i<selectingNumber; i++) {   //check if there is any duplicate index
    randomNum = Math.floor(Math.random() * totalIndex)
    if (randomIndexArray.indexOf(randomNum) === -1) {
      randomIndexArray.push(randomNum)
    } else { //if the randomNum is already in the array retry
      i--
    }
  }
  return randomIndexArray
}
profile
빵굽는 프론트엔드 개발자

0개의 댓글