考虑:

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


如何使用JavaScript从该数组中选择一个随机值?

#1 楼

这是一个简单的单行代码:
const randomElement = array[Math.floor(Math.random() * array.length)];

例如:



 const months = ["January", "February", "March", "April", "May", "June", "July"];

const random = Math.floor(Math.random() * months.length);
console.log(random, months[random]); 




评论


@SapphireSun,这是正确的。请注意Math.floor(Math.random(...))调用,该调用会四舍五入。

–ashes999
2014年1月19日,12:43

啊,我学到新东西了。我在讨论它等于1的情况,但显然(根据W3Schools)Math.random在0包含和1排除之间。我的错。

–SapphireSun
2014年1月20日,0:14

我可能是错的,但我记得var rand = myArray [Math.random()* myArray.length >> 0]要快一点

–vrugtehagel
16年7月22日在12:34

你的答案总是给第一阵?它不是随机值

–弗雷迪·西达鲁克(Freddy Sidauruk)
16/09/14'7:13

我更喜欢这种变体:var rand = myArray [Math.random()* myArray.length | 0]

–尼古拉斯(Nicolas)
18年8月29日在15:54



#2 楼

如果项目中已经包含下划线或破折号,则可以使用_.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);


,或在lodash中使用_.sampleSize方法:

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


评论


使用打字稿时:请注意,给定字符串数组,返回类型将是“ string | undefined”而不是“ string”。

–斯蒂芬·席尔克(Stephan Schielke)
5月6日18:18

#3 楼

原型方法
如果打算大量获取随机值,则可能要为其定义一个函数。
首先,将其放在代码中的某个位置:
Array.prototype.sample = function(){
  return this[Math.floor(Math.random()*this.length)];
}

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


根据CC0 1.0许可的条款将代码发布到公共领域。

评论


这是做什么的?

–肯·夏普
18年1月23日在1:26

@KenSharp它允许您在任何数组上调用.sample()以获取随机项

–本·奥宾
18年1月23日在2:07

应避免扩展本机对象类型。我删除了我的答案,因为看到了很多建议,但提倡不良做法。有关此问题的更多讨论,请参见stackoverflow.com/questions/14034180/…和eslint.org/docs/rules/no-extend-native

– Markus Amalthea Magnuson
19/12/6在17:23

#4 楼

~~Math.Floor()快得多,因此,在使用UI元素生成输出的同时进行性能优化时,~~胜出了。更多信息
var rand = myArray[~~(Math.random() * myArray.length)];

但是,如果您知道该数组将拥有数百万个元素,那么您可能不希望在Bitwise Operator和Math.Floor()之间重新考虑,因为bitwise运算符对大量数字的行为很奇怪。参见下面的示例,对输出进行解释。更多信息(失效链接)
var number = Math.floor(14444323231.2); // => 14444323231
var number = 14444323231.2 | 0; // => 1559421343


评论


链接已经死了,但是有趣的帖子,我现在将比Math.floor使用它更多:)

–alistair
19年8月25日在8:12

使用“按位非”运算符虽然速度更快,但不易读,因此您必须选择对您更重要的内容

– MaciejUrbański
19年8月29日在17:55

#5 楼

假设您要选择与上次不同的随机项目(不是真正随机的,但仍然是常见要求)...
 /**
 * Return a random element from an array that is
 * different than `last` (as long as the array has > 1 items). 
 * Return null if the array is empty.
*/
function getRandomDifferent(arr, last = undefined) {
  if (arr.length === 0) {
    return;
  } else if (arr.length === 1) {
    return arr[0];
  } else {
    let num = 0;
    do {
      num = Math.floor(Math.random() * arr.length);
    } while (arr[num] === last);
    return arr[num];
  }
}
  
实现如下:
 const arr = [1,2,3];
const r1 = getRandomDifferent(arr);
const r2 = getRandomDifferent(arr, r1); // r2 is different than r1.
 


#6 楼

如果您具有固定值(例如月份名称列表)并且想要单行解决方案

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


数组的第二部分是访问操作,如为什么JavaScript中[5,6,8,7] [1,2] = 8是什么?

评论


这样的代码是一种坏习惯。切勿在生产中使用它。它具有较低的可读性,并且具有硬编码的数组长度。更改数组输入的人可能会忘记最后编辑硬编码的长度。

–海鸥
18年9月5日在22:50

@Seagull OP从来没有要求特定的环境。同样,此注释也没有意义,因为它可以应用于该问题的几乎所有答案;)

– I.G. Pascual
18年9月6日在14:36

但是大多数人都是通过Google搜索解决这个问题的,他们可能会在原始OP之外的其他情况下使用该解决方案。

–海鸥
18年9月9日在17:10

@Seagull Haha人们可以自由决定使用哪种方法,我不是清洁代码准则的常见问题!

– I.G. Pascual
18/09/10在15:45



我喜欢它的可读性,我自己也来到了相同的解决方案

–劳利·拉甘德(Rauli Rajande)
11月28日20:44

#7 楼

最短的版本:

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


评论


是什么0吗?

–肯·夏普
18年1月23日在1:27

与Math.floor相同,它将Float转换为Int。

– foxiris
18年1月23日在5:47

@KenSharp | 0本身是不执行任何操作的按位运算,但是在javascript中,浮点数会在进行任何按位运算之前转换为ints。因此,就像+''并没有真正做任何事情,而是可以将其转换为字符串。

–牧羊人
18-09-19在7:26



它与Math.floor不同,但这是正确的做法。它是一个运算符,因此它比Math.floor快,只要是因为在运行某些代码的任何时候都可以执行Math.floor = someOtherFunction,而它们对于'|'不能这样做。另一方面,对于Math.floor和|尝试使用Math.floor(-1.5)和-1.5 | 0.顺便说一下,您不需要括号。 |优先级很低。

– gman
19年6月5日在2:59

#8 楼

如果要像Pascual的解决方案一样将其写在一行上,另一种解决方案是使用ES6的find函数(根据事实,从n中随机选择一个的概率为1/n)来编写它:




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





将这种方法用于测试目的,如果有充分的理由不将数组仅保存在单独的变量中,则可以使用该方法。否则,其他答案(floor(random()*length并使用单独的函数)是您要走的路。

#9 楼

Faker.js具有许多用于生成随机测试数据的实用程序功能。在测试套件的上下文中,这是一个不错的选择:

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


正如评论者所提到的,通常不应在生产代码中使用此库。

评论


对于像这样的简单问题,不需要为整个库添加依赖项,这会使代码膨胀。如果有的话,您可能会推荐Faker的实际方法,该方法选择一个随机数组元素。

– Pixxl
17年12月21日在17:41

像这样的“简单问题”通常由图书馆解决,该图书馆为数百人已经面临的问题提供了简单的解决方案。这些库通常是健壮且调试良好的,并且处理了我们不想重新实现的各种警告。我通常会建议使用库。

– smonff
18年5月16日在7:59



比您应该从库中复制一个方法并将其放入utils文件中

–里克·布鲁斯
'18 -10-1在4:51

关于将库运送到Web浏览器时应评估WRT页面成本/收益的建议是合理的建议,我全心全意地同意将Faker.js运送到浏览器是荒谬的。但是,该问题未提及正在使用哪个JS运行时。对于基于NodeJS的运行时,较重的依赖性是完全合理的,在Cucumber JS测试套件中,我使用Faker.js的情况就是如此。

–内森(Nathan)
18-10-3在22:02

#10 楼

编辑数组原型可能是有害的。这是完成这项工作的简单功能。

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);


#11 楼

递归的独立函数,可以返回任意数量的项(与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])
}


#12 楼

要获得加密强度高的随机项目形式数组,请使用




 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) ) 




#13 楼

这类似于@Jacob Relkin的解决方案,但比它更笼统:

这是ES2015:

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


该代码通过选择一个在0和数组长度之间的随机数,然后返回该索引处的项目。

#14 楼

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); 




#15 楼

简单功能:

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


OR

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


OR

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


评论


最好在函数内设置myArrayy变量,以免污染全局名称空间。

–尼尔·迈尔(Neil Meyer)
18年3月19日在8:07

#16 楼

我认为,与其乱扔原型或及时声明,不如将其暴露在窗口中:

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)];
}


现在在应用程序中的任何位置都可以调用它like:

var rand = window.choice.call(array)


这样,您仍然可以正确使用for(x in array)循环

评论


当有人对它进行投票时,我不是在这里,也没有对它进行投票,但是我的猜测是,将其暴露给window基本上是在声明全局变量。请参阅:stackoverflow.com/questions/2613310/…

–克里斯
15年4月8日在21:30

永远不要在数组上使用...,甚至一般而言。您冒着走原型链的风险。这也意味着对象的所有属性,而不是数组中的所有索引。如果要在数组上使用迭代器,请使用for(var i = 0; i
–罗伯特
16年1月18日在20:20

我不喜欢这样做,因为它会污染全球范围。您可能会说这可能是唯一的一种,但是会养成违反这种良好做法的习惯。

–杰克
16年11月15日下午5:43

#17 楼

我已经找到了解决最复杂答案的方法,只需将变量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总是在这里改变...随机本身并没有改变它,并且没有其他东西被多次调用过了。

–BalinKingOfMoria恢复CM
2016年9月1日下午0:54

这种解决方案并不完全有意义。为什么要创建一个名为concat的变量?

–超级照明
17年5月15日在12:55

#18 楼




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





为数组设置一个常量变量,然后有了另一个常量,该常量在数组的三个对象之间随机选择,然后函数简单地返回结果。

#19 楼

寻找真正的单线飞机,我来了:
['January', 'February', 'March'].reduce((a, c, i, o) => { return o[Math.floor(Math.random() * Math.floor(o.length))]; })


#20 楼

通过在数组原型上添加一个方法,您可以轻松获得随机值。
在此示例中,您可以从数组中获取单个或多个随机值。
您可以通过单击代码片段按钮来运行测试代码。



 Array.prototype.random = function(n){
  if(n&&n>1){
    const a = [];
    for(let i = 0;i<n;i++){
      a.push(this[Math.floor(Math.random()*this.length)]);
    }
    return a;
  } else {
    return this[Math.floor(Math.random()*this.length)];
  }
}

const mySampleArray =  ['a','b','c','d','e','f','g','h'];

mySampleArray.random(); // return any random value etc. 'a', 'b'
mySampleArray.random(3); //retun an array with random values etc: ['b','f','a'] , ['d','b','d']

alert(mySampleArray.random());
alert(mySampleArray.random(3)); 




#21 楼

获取随机元素的通用方法:




 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;
} 




#22 楼

以下是操作方法示例:

$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)];


#23 楼

randojs使此操作更加简单易读:




 console.log( rando(['January', 'February', 'March']).value ); 

 <script src="https://randojs.com/1.0.0.js"></script> 




评论


有些人不喜欢向图书馆采购他们可以自己编写的代码,即使这样做会使事情变得更快,更易读。如果图书馆由于某种原因而关闭,则您的网站现在出现故障。 randojs并没有失败,但是他们不知道,因为它不像jQuery之类的库那么知名

–亚伦Plocharczyk
2月21日在2:56



#24 楼

创建一个随机值并传递给数组

请尝试以下代码。.

//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);


评论


该答案使用与已经接受的答案相同的解决方案。您应该避免两次添加相同的解决方案,而只能提出其他可能有助于对话的替代方案。

– Pixxl
17年12月21日在17:44