考虑:
var myArray = ['January', 'February', 'March'];
如何使用 JavaScript 从这个数组中选择一个随机值?
这是一个简单的单行:
const randomElement = array[Math.floor(Math.random() * array.length)];
例如:
const 月 = [“一月”、“二月”、“三月”、“四月”、“五月”、“六月”、“七月”]; const random = Math.floor(Math.random() * months.length); console.log(随机,月[随机]);
如果您的项目中已包含 underscore 或 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);
或使用 lodash 中的 _.sampleSize
方法:
// will return two items randomly from the array using lodash
_.sampleSize(['January', 'February', 'March'], 2);
您可以考虑在 Array 原型上定义一个函数,以创建一个返回随机元素的方法 [].sample()
。
首先,要定义原型函数,请将此代码段放入您的代码中:
Array.prototype.sample = function(){
return this[Math.floor(Math.random()*this.length)];
}
稍后,要从数组中采样一个随机元素,只需调用 .sample()
:
[1,2,3,4].sample() //=> a random element
我将根据 CC0 1.0 license 的条款将这些代码片段发布到公共领域。
.sample()
以获取随机项
~~
比 Math.Floor()
快得多,因此在使用 UI 元素生成输出时的性能优化方面,~~
胜出。 MORE INFO
var rand = myArray[~~(Math.random() * myArray.length)];
但是,如果您知道该数组将包含数百万个元素,那么您可能需要重新考虑位运算符和 Math.Floor()
之间的关系,因为位运算符在处理大量数字时会表现得很奇怪。请参见下面的示例,其中解释了输出。
var number = Math.floor(14444323231.2); // => 14444323231
var number = 14444323231.2 | 0; // => 1559421343
Math.floor
:)
~
是按位的 not
,它将二进制数中的 1
和 0
反转。与所有按位运算符一样,它首先将数字转换为您真正想要的 32 位整数。使用 ~~
将原始数据恢复为 32 位整数。
Math.floor()
,所有函数都有开销,包括存储和恢复原始状态。通常,优化编译器会寻找机会将代码复制到适当的位置以避免这种开销,但是对于 JavaScript 这样的动态语言,它更难预测。
最短的版本:
var myArray = ['一月','二月','三月']; var rand = myArray[(Math.random() * myArray.length) | 0] 控制台日志(兰德)
| 0
有什么作用?
| 0
本身是一个不执行任何操作的按位运算,但在 javascript 中,浮点数是 converted to ints before any bitwise operation。所以这有点像 + ''
并没有真正做任何事情,但可以用来将事物转换为字符串。
Math.floor
不同,但它是正确的做法。它是一个运算符,所以它比 Math.floor
快,因为在任何时候运行一些代码都可以做 Math.floor = someOtherFunction
而他们不能对 '|' 做同样的事情。另一方面,对于 Math.floor
和 |
不同,请尝试 Math.floor(-1.5)
与 -1.5 | 0
。顺便说一句,你不需要括号。 |
的优先级很低。
假设您要选择与上次不同的随机项目(不是真正随机的,但仍然是常见的要求)...
/**
* 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 null;
} 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.
如果您有固定值(如月份名称列表)并想要一个单行解决方案
var result = ['January', 'February', 'March'][Math.floor(Math.random() * 3)]
数组的第二部分是访问操作,如 Why does [5,6,8,7][1,2] = 8 in JavaScript? 中所述
如果你想把它写在一行上,就像 Pascual 的解决方案一样,另一种解决方案是使用 ES6 的 find 函数来编写它(基于这样一个事实,从 n
个项目中随机选择一个项目的概率是 1/n
):
var item = ['A', 'B', 'C', 'D'].find((_, i, ar) => Math.random() < 1 / (ar.length - i));控制台.log(项目);
将该方法用于测试目的,并且如果有充分的理由不将数组仅保存在单独的变量中。否则,其他答案(floor(random()*length
并使用单独的函数)是您的选择。
Faker.js 具有许多用于生成随机测试数据的实用函数。在测试套件的上下文中,这是一个不错的选择:
const Faker = require('faker');
Faker.random.arrayElement(['January', 'February', 'March']);
正如评论者所提到的,您通常不应该在生产代码中使用这个库。
Faker
的实际方法,该方法选择一个随机数组元素。
如果您需要多次获取随机项目,那么显然您将使用一个函数。一种方法是使该函数成为 Array.prototype
的方法,但这通常会让您因篡改内置原型而大喊大叫。
但是,您可以将该方法添加到特定数组本身:
var months = ['January', 'February', 'March'];
months.random = function() {
return this[Math.floor(Math.random()*this.length)];
};
这样您就可以随意使用 months.random()
,而不会干扰通用的 Array.prototype
。
与任何随机函数一样,您冒着连续获得相同值的风险。如果您不希望这样,您将需要使用另一个属性来跟踪先前的值:
months.random=function() {
var random;
while((random=this[Math.floor(Math.random()*this.length)]) == this.previous);
this.previous=random;
return random;
};
如果您要经常执行此类操作,并且不想篡改 Array.prototype
,则可以执行以下操作:
function randomValue() {
return this[Math.floor(Math.random()*this.length)];
}
var data = [ … ];
var moreData = [ … ];
data.random=randomValue;
moreData.random=randomValue;
编辑数组原型可能是有害的。这是一个简单的功能来完成这项工作。
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);
要获得 crypto-strong 随机项形式数组,请使用
让 rndItem = a=> a[rnd()*a.length|0];让 rnd = ()=> crypto.getRandomValues(new Uint32Array(1))[0]/2**32; var myArray = ['一月','二月','三月'];控制台日志(rndItem(myArray))
可以返回任意数量的项目的递归独立函数(与 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])
}
这类似于@Jacob Relkin 的解决方案,但更通用:
这是 ES2015:
const randomChoice = arr => {
const randIndex = Math.floor(Math.random() * arr.length);
return arr[randIndex];
};
该代码通过在 0 和数组长度之间选择一个随机数来工作,然后返回该索引处的项目。
var item = myArray[Math.floor(Math.random()*myArray.length)];
或等效的较短版本:
var item = myArray[(Math.random()*myArray.length)|0];
示例代码:
var myArray = ['一月','二月','三月']; var item = myArray[(Math.random()*myArray.length)|0]; console.log('item:', item);
简单功能:
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();
在我看来,比弄乱原型或及时声明它更好,我更喜欢将它暴露在窗口中:
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)
循环
for...in
,甚至一般情况下。你冒着走原型链的风险。它也适用于对象的所有属性,而不是数组中的所有索引。如果要对数组使用迭代器,请使用 for (var i = 0; i < foo.length; i++){}
。更好的是,改用 Array.prototype.forEach
之类的东西。
我找到了解决最佳答案复杂性的方法,只需将变量 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
本身并没有改变它,而且没有其他任何东西被多次调用......
静态 generateMonth() { const theDate = ['一月','二月','三月']; const randomNumber = Math.floor(Math.random()*3);返回日期[随机数]; };
你为数组设置一个常量变量,然后你有另一个常量在数组中的三个对象之间随机选择,然后函数简单地返回结果。
寻找一个真正的单线我来到这个:
['January', 'February', 'March'].reduce((a, c, i, o) => { return o[Math.floor(Math.random() * Math.floor(o.length))]; })
通过在数组原型上添加方法,您可以轻松获得随机值。
在此示例中,您可以从数组中获取单个或多个随机值。
您可以通过单击代码片段按钮运行测试代码。
Array.prototype.random = function(n){ if(n&&n>1){ const a = []; for(让 i = 0;i
方法一:
使用 Math.random() 函数获取(0-1, 1 除外)之间的随机数。
将它乘以数组长度以获得(0-arrayLength)之间的数字。
使用 Math.floor() 获取范围从 (0 到 arrayLength-1) 的索引。
常量 arr = ["foo","bar"]; const randomPickedString=arr[Math.floor(Math.random() * arr.length)]; console.log(randomlyPickedString);
方法二:
random(a, b) 方法用于生成介于(a 到 b,b 除外)之间的数字。
取下限值以将数字范围从(1 到 arrayLength)。
减 1 得到从 (0 到 arrayLength-1) 的索引。
常量 arr = ["foo","bar"]; const randomPickedString=arr[Math.floor(random(1, 5))-1]; console.log(randomlyPickedString);
获取随机元素的通用方法:
let some_array = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];让月 = random_elems(some_array, 3); console.log(月);函数 random_elems(arr, count) { 让 len = arr.length;让查找 = {};让 tmp = [];如果(计数 > 长度)计数 = 长度; for (let i = 0; i < count; i++) { 让索引;做 { index = ~~(Math.random() * len); } 而(查找中的索引);查找[索引] = null; tmp.push(arr[index]); } 返回时间; }
以下是如何执行此操作的示例:
$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)];
创建一个随机值并传递给数组
请尝试以下代码..
//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);
randojs 使它更简单易读:
console.log(rando(['一月', '二月', '三月']).value );
我真的很惊讶没有人尝试使用本机随机值:
array[Date.now()%array.length]
它不适用于长度超过 160000000000 的数组,但我相信你永远不会创建这样的数组
UPD
至于你的问题是如何从名为 myArray
的数组中选择随机值(len = 3),解决方案应该是:
myArray[Date.now()%myArray.length]
Date.now()
与随机性无关,并且确实具有相当的确定性。我知道在某些用例中它可能感觉足够“随机”
Date.now()
每次都返回不同的值,这样就无法确定 100% 的准确度,此外,如果数组大约有 3 个元素。
Math.Rand
个已实现的解决方案,只要它是一个伪随机函数
Math.floor(Math.random(...))
调用,它向下取整。var rand = myArray[Math.random() * myArray.length>>0]
稍微快一点var rand = myArray[Math.random() * myArray.length | 0]
Math.floor
而不是Math.trunc
?