자바 스크립트 배열에서 임의의 값 얻기


793

치다:

var myArray = ['January', 'February', 'March'];    

JavaScript를 사용하여이 배열에서 임의의 값을 선택하려면 어떻게해야합니까?

답변:


1480

간단한 원 라이너

const randomElement = array[Math.floor(Math.random() * array.length)];

const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const randomMonth = months[Math.floor(Math.random() * months.length)];

console.log("random month =>", randomMonth);


9
@SapphireSun 이것이 맞습니다. Math.floor(Math.random(...))반올림 되는 호출에 유의하십시오 .
ashes999

33
아, 나는 새로운 것을 배웠다. 정확히 1과 같지만 (W3Schools에 따르면) Math.random은 0에서 1 사이의 배타적입니다. 내 잘못이야.
SapphireSun

13
제가 틀릴 수도 있지만, 내가 기억 var rand = myArray[Math.random() * myArray.length>>0]되는 약간 빠른
vrugtehagel

6
만약 이미 lodash를 사용하고 있다면 _.sample (array)을 사용할 수 있습니다
Gabriel Matusevich

2
나는이 변형을 선호한다 :var rand = myArray[Math.random() * myArray.length | 0]
Nicolas

76

이미 밑줄 이나 lodash가 프로젝트에 포함되어 있다면를 사용할 수 있습니다 _.sample.

// will return one item randomly from the array
_.sample(['January', 'February', 'March']);

하나 이상의 항목을 무작위로 가져와야하는 경우 밑줄에서 두 번째 인수로 해당 항목을 전달할 수 있습니다.

// will return two items randomly from the array using underscore
_.sample(['January', 'February', 'March'], 2);

또는 _.sampleSizelodash 에서 메소드를 사용하십시오 .

// will return two items randomly from the array using lodash
_.sampleSize(['January', 'February', 'March'], 2);

타입 스크립트를 사용하는 경우 : 문자열 타입이 주어지면 반환 타입은 "string"대신 "string | undefined"가됩니다.
Stephan Schielke

23

프로토 타입 방법

임의의 값을 많이 얻으려는 경우 함수를 정의 할 수 있습니다.

먼저 이것을 코드 어딘가에 넣으십시오.

Array.prototype.sample = function(){
  return this[Math.floor(Math.random()*this.length)];
}

지금:

[1,2,3,4].sample() //=> a random element

CC0 1.0 라이센스 조건에 따라 퍼블릭 도메인으로 공개 된 코드 .


그리고 이것은 무엇을합니까?
Ken Sharp

3
@ KenSharp 그것은 당신 .sample()이 임의의 항목을 얻기 위해 어떤 배열 을 호출 할 수 있습니다
Ben Aubin

5
기본 객체 유형을 확장하지 않아야합니다. 답변이 많이 삭제 된 것을보고 답변을 삭제했지만 좋지 않은 연습을 장려합니다. 이 문제에 대한 자세한 설명은 예를 참조 stackoverflow.com/questions/14034180/...eslint.org/docs/rules/no-extend-native
마르쿠스 아말 테아 매그너 슨

20

~~보다 훨씬 빠르 Math.Floor()므로 UI ​​요소를 사용하여 출력을 생성하는 동안 성능 최적화와 관련 ~~하여 게임 에서 승리합니다. 더 많은 정보

var rand = myArray[~~(Math.random() * myArray.length)];

그러나 Math.Floor()비트 연산자가 큰 숫자로 이상하게 작동 하기 때문에 배열에 수백만 개의 요소가 있음을 알고 있다면 Bitwise Operator와 사이를 다시 생각할 수 있습니다. 출력과 함께 설명 된 아래 예를 참조하십시오. 더 많은 정보

var number = Math.floor(14444323231.2); // => 14444323231
var number = 14444323231.2 | 0; // => 1559421343

1
링크는 죽은 그러나 흥미로운 게시물 내가 이상이 이상을 사용하여야한다 Math.floor: 지금
aabbccsmith

"bitwise not"연산자를 사용하는 것이 더 빠르기는하지만 읽을 수있는 것은 아니므로 더 중요한 것을 선택해야합니다.
Maciej Urbański

16

마지막 시간과 다른 무작위 항목을 선택한다고 가정하십시오 (실제로 무작위는 아니지만 여전히 일반적인 요구 사항) ...

@Markus의 답변을 바탕으로 다른 프로토 타입 함수를 추가 할 수 있습니다.

Array.prototype.randomDiffElement = function(last) {
   if (this.length == 0) {
      return;
   } else if (this.length == 1) {
      return this[0];
   } else {
      var num = 0;
      do {
         num = Math.floor(Math.random() * this.length);
      } while (this[num] == last);
      return this[num];
   }
}

그리고 다음과 같이 구현하십시오.

var myRandomDiffElement = myArray.randomDiffElement(lastRandomElement)

11

월 이름 목록과 같은 고정 값이 있고 한 줄 솔루션을 원할 경우

var result = ['January', 'February', 'March'][Math.floor(Math.random() * 3)]

배열의 두 번째 부분은 JavaScript에서 [5,6,8,7] [1,2] = 8 인 이유에 설명 된 액세스 작업입니다 .


2
이러한 코드는 나쁘고 해로운 행위입니다. 프로덕션에서는 절대 사용해서는 안됩니다. 가독성이 낮고 하드 코드 된 배열 길이를 갖습니다. 배열 입력을 변경하는 사람은 끝에 하드 코딩 된 길이를 편집하는 것을 잊어 버릴 수 있습니다.
갈매기

@Seagull OP는 특정 환경을 요구하지 않았습니다. 또한이 의견은이 질문의 거의 모든 답변에 적용될 수 있으므로 의미가 없습니다.)
IG Pascual

그러나 대부분의 사람들은 Google 검색 에서이 질문에 도달하며 원래 OP 이외의 다른 시나리오에서 솔루션을 사용할 수 있습니다.
갈매기

@Seagull Haha 사람들은 어떤 접근 방식을 사용할지 자유롭게 결정할 수 있습니다. 나는 깨끗한 코드 지침이 아닙니다!
IG Pascual

10

가장 짧은 버전 :

var myArray = ['January', 'February', 'March']; 
var rand = myArray[(Math.random() * myArray.length) | 0]

무엇을 | 0합니까?
Ken Sharp

2
Math.floor와 마찬가지로 Float를 Int로 바꿉니다.
foxiris

4
@KenSharp | 0자체는 아무것도하지 않는 비트 단위 연산이지만, 자바 스크립트에서는 float 연산이 비트 단위 연산 전에 int로 변환됩니다 . 그래서 그것은 + ''실제로 아무것도하지 않는 방법과 비슷 하지만 물건을 문자열로 변환하는 데 사용될 수 있습니다.
dshepherd

그것은 동일하지 Math.floor않지만 여기에서 올바른 일입니다. 연산자이므로 Math.floor일부 코드를 실행하는 동안 언제든지 Math.floor = someOtherFunction'|'에 대해 동일한 작업을 수행 할 수 없기 때문에 보다 빠릅니다 . 의 경우와 다른 한편 Math.floor|다른 시도되는 Math.floor(-1.5)-1.5 | 0. 그건 그렇고 괄호가 필요하지 않습니다. |우선 순위가 매우 낮습니다.
gman

7

Pascual의 솔루션과 같이 한 줄에 작성하려면 ES6의 찾기 기능을 사용하여 작성하십시오 (사실, n항목 중 하나를 임의로 선택할 확률 은 1/n).

var item = ['A', 'B', 'C', 'D'].find((_, i, ar) => Math.random() < 1 / (ar.length - i));
console.log(item);

테스트 목적으로 그리고 별도의 변수에만 배열을 저장하지 않는 적절한 이유가있는 경우이 방법을 사용하십시오. 그렇지 않으면 다른 답변 ( floor(random()*length및 별도의 기능 사용)을 사용하는 것이 좋습니다.


매우 독창적 인 솔루션. 잘 했어! 그건 그렇고, 여기에서 유일한 실제적이고 역동적 인 원 라이너 솔루션.
Slavik Meltser

7

Faker.js 에는 무작위 테스트 데이터를 생성하기위한 많은 유틸리티 기능이 있습니다. 테스트 스위트와 관련하여 좋은 옵션입니다.

const Faker = require('faker');
Faker.random.arrayElement(['January', 'February', 'March']);

주석 작성자가 언급했듯이 일반적으로 프로덕션 라이브러리에서는이 라이브러리를 사용하지 않아야합니다.


8
이와 같은 간단한 문제의 경우 전체 라이브러리에 대한 종속성을 추가 할 필요가 없으며 코드 팽창이 추가됩니다. 그렇다면 Faker임의의 배열 요소를 선택하는 실제 방법을 권장 할 수 있습니다 .
Pixxl

1
이와 같은 "단순한 문제"는 보통 수백 명의 사람들이 이미 직면했던 문제에 대한 간단한 해결책을 제공하는 라이브러리로 해결됩니다. 이러한 라이브러리는 일반적으로 강력하고 잘 디버깅되어 있으며 다시 구현하고 싶지 않은 다양한 경고를 처리합니다. 일반적으로 라이브러리 사용을 권장하는 상황입니다.
몬프

라이브러리에서 그 하나의 메소드를 복사하여 utils 파일에 넣으십시오
Rick Bross

라이브러리가 웹 브라우저에 제공 될 때 비용 / 혜택 WRT 페이지 가중치에 대해 라이브러리를 평가해야한다는 조언은 건전한 조언이며 Faker.js를 브라우저에 제공하는 것은 말도 안된다는 데 전적으로 동의합니다. 그러나 질문은 어떤 JS 런타임이 사용되고 있는지 언급하지 않습니다. NodeJS 기반 런타임의 경우 Cucumber JS 테스트 스위트에서 Faker.js를 사용하는 경우와 같이 더 큰 종속성이 완벽하게 합리적입니다.
Nathan

6

배열 프로토 타입 편집은 해로울 수 있습니다. 다음은 작업을 수행하는 간단한 기능입니다.

function getArrayRandomElement (arr) {
  if (arr && arr.length) {
    return arr[Math.floor(Math.random() * arr.length)];
  }
  // The undefined will be returned if the empty array was passed
}

용법:

// Example 1
var item = getArrayRandomElement(['January', 'February', 'March']);

// Example 2
var myArray = ['January', 'February', 'March'];
var item = getArrayRandomElement(myArray);

3

임의의 수의 항목을 리턴 할 수있는 재귀 독립형 함수 ( lodash.sampleSize와 동일 ) :

function getRandomElementsFromArray(array, numberOfRandomElementsToExtract = 1) {
    const elements = [];

    function getRandomElement(arr) {
        if (elements.length < numberOfRandomElementsToExtract) {
            const index = Math.floor(Math.random() * arr.length)
            const element = arr.splice(index, 1)[0];

            elements.push(element)

            return getRandomElement(arr)
        } else {
            return elements
        }
    }

    return getRandomElement([...array])
}

2

얻으려면 암호 강력한 임의 항목 형태로 배열 사용

let rndItem = a=> a[rnd()*a.length|0];
let rnd = ()=> crypto.getRandomValues(new Uint32Array(1))[0]/2**32;

var myArray = ['January', 'February', 'March'];

console.log( rndItem(myArray) )


1

이것은 @Jacob Relkin의 솔루션과 비슷하지만 더 일반적입니다.

이것은 ES2015입니다.

const randomChoice = arr => {
    const randIndex = Math.floor(Math.random() * arr.length);
    return arr[randIndex];
};

이 코드는 0과 배열 길이 사이의 임의의 숫자를 선택한 다음 해당 인덱스에서 항목을 반환하여 작동합니다.


1

var item = myArray[Math.floor(Math.random()*myArray.length)];

또는 동등한 더 짧은 버전 :

var item = myArray[(Math.random()*myArray.length)|0];

샘플 코드 :

var myArray = ['January', 'February', 'March'];    
var item = myArray[(Math.random()*myArray.length)|0];
console.log('item:', item);


1

간단한 기능 :

var myArray = ['January', 'February', 'March'];
function random(array) {
     return array[Math.floor(Math.random() * array.length)]
}
random(myArray);

또는

var myArray = ['January', 'February', 'March'];
function random() {
     return myArray[Math.floor(Math.random() * myArray.length)]
}
random();

또는

var myArray = ['January', 'February', 'March'];
function random() {
     return myArray[Math.floor(Math.random() * myArray.length)]
}
random();

전역 네임 스페이스를 오염시키지 않도록 함수 내에 myArrayy 변수를 설정하는 것이 좋습니다.
Neil Meyer

0

내 생각에, prototype을 엉망으로 만들거나 제 시간에 선언하는 것보다 창에 노출시키는 것을 선호합니다.

window.choice = function() {
  if (!this.length || this.length == 0) return;
  if (this.length == 1) return this[0];
  return this[Math.floor(Math.random()*this.length)];
}

이제 앱 어디에서나 다음과 같이 호출합니다.

var rand = window.choice.call(array)

이렇게하면 여전히 for(x in array)루프를 올바르게 사용할 수 있습니다


1
누군가가 그것을 downvoted했을 때 여기에 없었고 그것을 downvote하지 않았지만, 내 생각에 그것을 창에 노출시키는 것은 기본적으로 전역 변수를 선언하는 것입니다. 참조 : stackoverflow.com/questions/2613310/...
크리스

1
for...in배열이나 일반적으로 사용해서는 안됩니다 . 프로토 타입 체인을 걸을 위험이 있습니다. 또한 배열의 모든 인덱스가 아니라 객체의 모든 속성을 의미합니다. 배열에서 반복자를 사용하려면을 사용하십시오 for (var i = 0; i < foo.length; i++){}. 더 좋은 방법은 Array.prototype.forEach대신 비슷한 것을 사용하십시오.
Robert

1
전 세계 범위를 오염시키기 때문에 이것을 선호하지 않습니다. 당신은 이것이 유일한 존재라고 말할 수 있지만, 그것은 좋은 습관을 어기는 습관을 줄 것입니다.
Jekk

0

변수 rand를 다른 변수에 연결하여 myArray [];의 호출 안에 해당 숫자를 표시 할 수 있도록하여 최상위 답변의 복잡성을 피할 수있는 방법을 찾았습니다. 생성 된 새로운 배열을 삭제하고 합병증을 극복함으로써 효과적인 해결책을 찾았습니다.

<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>

var myArray = ['January', 'February', 'March', 'April', 'May'];    

var rand = Math.floor(Math.random() * myArray.length);

var concat = myArray[rand];

function random() {
   document.getElementById("demo").innerHTML = (concat);
}
</script>

<button onClick="random();">
Working Random Array generator
</button>

</body>
</html>

그 이유를 혼동하고있어 concat지금 여기에 변화 ... random... 자체는 변경되지 않으며, 아무것도 두 번 이상 호출되지지고
BalinKingOfMoria 분석 재개 CM이

1
이 솔루션은 전적으로 의미가 없습니다. concat이라는 변수를 만드는 이유는 무엇입니까?
superluminary

0

static generateMonth() { 
const theDate = ['January', 'February', 'March']; 
const randomNumber = Math.floor(Math.random()*3);
return theDate[randomNumber];
};

상수 변수를 배열로 설정하면 배열의 세 객체 사이에서 무작위로 선택되는 다른 상수가 있고 함수는 단순히 결과를 반환합니다.


-1

임의의 요소를 얻는 일반적인 방법 :

let some_array = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];
let months = random_elems(some_array, 3);

console.log(months);

function random_elems(arr, count) {
  let len = arr.length;
  let lookup = {};
  let tmp = [];

  if (count > len)
    count = len;

  for (let i = 0; i < count; i++) {
    let index;
    do {
      index = ~~(Math.random() * len);
    } while (index in lookup);
    lookup[index] = null;
    tmp.push(arr[index]);
  }

  return tmp;
}


-1

randojs 는 이것을 좀 더 단순하고 읽기 쉽게 만듭니다.

console.log( rando(['January', 'February', 'March']).value );
<script src="https://randojs.com/1.0.0.js"></script>


1
궁금한 점은 왜 다운 보트인가?
레 폰조

1
어떤 사람들은 더 빠르고 읽기 쉬운 코드를 만들더라도 스스로 작성할 수있는 코드를 라이브러리에서 소싱하는 팬이 아닙니다. 어떤 이유로 라이브러리가 다운되면 웹 사이트에 결함이있는 것입니다. randojs는 다운되지 않지만 jQuery와 같은 라이브러리로는 잘 알려지지 않았기 때문에 알 수 없습니다.
Aaron Plocharczyk

-2

방법은 다음과 같습니다.

$scope.ctx.skills = data.result.skills;
    $scope.praiseTextArray = [
    "Hooray",
    "You\'re ready to move to a new skill", 
    "Yahoo! You completed a problem", 
    "You\'re doing great",  
    "You succeeded", 
    "That was a brave effort trying new problems", 
    "Your brain was working hard",
    "All your hard work is paying off",
    "Very nice job!, Let\'s see what you can do next",
    "Well done",
    "That was excellent work",
    "Awesome job",
    "You must feel good about doing such a great job",
    "Right on",
    "Great thinking",
    "Wonderful work",
    "You were right on top of that one",
    "Beautiful job",
    "Way to go",
    "Sensational effort"
  ];

  $scope.praiseTextWord = $scope.praiseTextArray[Math.floor(Math.random()*$scope.praiseTextArray.length)];

-2

또 다른 쉬운 방법 :

var myArray = ['keke','keko','cano','halo','zirto'];

var randomValue = myArray[Math.round((Math.random()*1000))%myArray.length];

-3

하나의 임의의 값을 만들고 배열로 전달

다음 코드를 시도하십시오 ..

//For Search textbox random value
var myPlaceHolderArray = ['Hotels in New York...', 'Hotels in San Francisco...', 'Hotels Near Disney World...', 'Hotels in Atlanta...'];
var rand = Math.floor(Math.random() * myPlaceHolderArray.length);
var Placeholdervalue = myPlaceHolderArray[rand];

alert(Placeholdervalue);

5
이 답변은 이미 수락 된 답변과 동일한 솔루션을 사용합니다. 동일한 솔루션을 두 번 추가하지 말고 대화에 더 많은 기여를 할 수있는 다른 대안 만 제시하십시오.
Pixxl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.