JavaScript 배열에서 랜덤으로 N개 추출하기
JavaScript 배열에서 랜덤으로 N개 추출하기
페이지를 불러오는 중...
주환
개발자
배열 전체가 아니라 그중 몇 개만 무작위로 뽑아 쓰는 패턴이 필요할 때가 있습니다. 추천 문구, 옵션 목록, 퀵 리플라이 등에서 “매번 다른 조합”을 보여주려면, 배열을 복사 → 셔플 → 앞에서 N개만 잘라 반환하는 방식으로 구현할 수 있습니다.
이 글에서는 이 흐름을 단계별로 자세히 다룹니다.
먼저 추출할 문자열(또는 객체) 목록을 배열로 둡니다. 아래는 예시이고, 실제로는 수십~수백 개가 들어갈 수 있습니다.
역할: 위 배열을 원본은 건드리지 않은 채 복사한 뒤, 순서를 무작위로 섞고, 그중 앞에서부터 count개만 잘라 반환합니다.
이제 각 줄이 왜 필요한지, 어떤 부작용을 막는지까지 포함해 자세히 설명합니다.
count 결정이 한 줄이 하는 일은 두 가지입니다.
① 기본값 부여: count || 3
count가 undefined, null, 0 등 falsy면 3을 사용합니다.slice(0, count)에서 일관된 동작을 합니다.② 상한 제한: Math.min(..., QUICK_REPLIES.length)
count가 배열 길이보다 크면, 그대로 두면 논리적으로 “전체를 반환”이지만, 의도는 “최대 N개”로 두는 경우가 많습니다.Math.min으로 배열 길이를 넘지 않도록 막아 두면, 다른 코드에서 “항상 count개 이하”라고 가정해도 안전합니다.QUICK_REPLIES.length가 0이므로, count는 0이 되고, 아래에서 빈 배열이 반환됩니다.정리하면, “몇 개를 뽑을지”를 안전하고 예측 가능하게 만드는 단계입니다.
QUICK_REPLIES.slice()여기서는 복사와 정렬(셔플) 두 가지가 함께 일어납니다. 먼저 복사부터 설명합니다.
Array.prototype.sort() 는 원본 배열을 그대로 수정합니다(in-place).QUICK_REPLIES를 직접 정렬하면, 한 번 호출할 때마다 원본 문구 순서가 바뀌어, 다음 호출이나 화면 다른 곳에서 같은 배열을 쓰는 경우 문제가 됩니다.slice() 는 인자 없이 호출하면 배열 전체를 얕은 복사한 새 배열을 반환합니다. 원본과 요소는 같지만 다른 배열 객체이므로, 이 복사본에만 sort를 적용하면 원본은 항상 그대로 유지됩니다.그래서 “원본 불변”을 지키기 위해 반드시 QUICK_REPLIES.slice() 로 복사한 뒤, 그 결과에 대해서만 아래 sort를 호출하는 것입니다.
sort에 랜덤 비교 함수 사용sort는 비교 함수의 반환값으로 정렬 순서를 결정합니다.
여기서는 매번 Math.random() - 0.5 를 반환합니다.
Math.random()은 [0, 1) 구간의 실수이므로, 0.5를 하면 약 절반은 음수, 절반은 양수가 됩니다.이 방식은 수학적으로 완벽히 균등한 분포는 아니지만, “몇 개만 랜덤하게 보여주기” 같은 용도에서는 구현이 단순하고 충분히 쓸 만합니다. 균등 분포가 중요하면 나중에 Fisher–Yates 셔플로 바꿀 수 있다는 점만 언급해 두면 좋습니다.
shuffled.slice(0, count)shuffled는 이미 위에서 무작위 순서로 재배치된 배열입니다.slice(0, count) 는 인덱스 0부터 count개를 잘라 새 배열로 반환합니다. shuffled 자체는 수정하지 않습니다.반환 타입은 원본 배열 요소 타입과 같습니다. 여기서는 문자열 배열이므로 string[]입니다.
다른 스크립트에서 이 함수와 배열을 쓰려면 전역 객체에 붙여 둘 수 있습니다.
window에 넣어 두면 다른 파일에서 FaqQuickChat.getRandomQuickReplies(5) 처럼 호출할 수 있습니다.FaqQuickChat)은 프로젝트에 맞게 바꿔서 사용하면 됩니다.입력: count (선택, 기본 3)
출력: 원본과 같은 타입의 요소로 이루어진, 길이 count 이하의 배열 (원본은 변경되지 않음)
slice()로 복사한 뒤에만 sort를 적용해, 원본 배열은 절대 바뀌지 않습니다.Math.min으로 count가 배열 길이를 넘지 않게 해서, 빈 슬라이스나 잘못된 가정을 방지합니다.sort에 Math.random() - 0.5를 넣어 비교 결과를 랜덤화하는 간단한 패턴을 사용합니다.
댓글