从JavaScript数组中获取一个随机项。

1475
var items = Array(523, 3452, 334, 31, ..., 5346);

如何从 items 中获取随机项?


428
回答不涉及jQuery。 - Alnitak
55
我从来没有见过这么多完全相同的答案回答一个问题… - Blindy
11
伟大的思想,@Blindy - Kelly
37
我找到了一个可以使用jQuery的方法!!(请看我的第二个回答) - Alnitak
12
这个问题几乎和从数组中获取随机值完全相同,但强大的Moderators在3年多的时间里没有关闭它。相反,他们关闭了那些有数百票的“无建设性”的问题,比如什么是Meteor、Ember.js和Backbone.js之间的关键差异? - Dan Dascalescu
显示剩余3条评论
13个回答

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

183
Math.random()永远不会是1,也不应该是。最大的索引应该始终比长度小1,否则你将得到一个“undefined”错误。 - Kelly
37
优雅的解决方案。我已经测试过:`var items = ["a","e","i","o","u"]` `var objResults = {}` `for(var i = 0; i < 1000000; i++){` `var randomElement = items[Math.floor(Math.random()*items.length)]` `if (objResults[randomElement]){` `objResults[randomElement]++` `}else{` `objResults[randomElement] = 1` `}` `}` `console.log(objResults)`在一百万次迭代后,结果相当随机:`Object {u: 200222, o: 199543, a: 199936, e: 200183, i: 200116}` - Johann Echavarria
23
“Math.round”不能代替“Math.floor”,使用“round”可能会导致意外引用未定义的索引,例如当“Math.random()”为0.95且“items.length”为5时。 “Math.round(0.95 * 5)”为5,这将是一个无效的索引。在您的示例中,“floor(random)”将始终为零。 - Kelly
34
好的回答。你可以更简洁一些:items[items.length * Math.random() | 0] :) - aloisdg
3
没错,只要数组长度小于2^31,那已经是一个非常大的数字了 :) - Kelly
显示剩余5条评论

155

1. 解决方案:定义数组原型

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

能够在内联数组上运行的代码

[2,3,5].random()

当然还有预定义数组

var list = [2,3,5]
list.random()

2. 解决方案:定义一个自定义函数,该函数接受列表并返回元素。

function get_random (list) {
  return list[Math.floor((Math.random()*list.length))];
}


get_random([2,3,5])

38
@EvanCarroll 最好提供一个有用的链接,而不是基于主观看法如编码风格这样的东西进行负评,因为这不会使答案无效或“无用”!https://dev59.com/T2Yr5IYBdhLWcg3wAFg0 - Simon
33
因为没有解释,对于将东西添加到Array.prototype中进行downvote是没有用的,所以我点赞了。 - AlexanderGriffin
3
将一个新函数添加到Array.prototype的问题与添加全局变量的问题相同——别人/其他东西可能正在使用相同的“名称”表示不同的内容,这可能会导致微妙的混乱。 - Schmoo
2
@Schmoo 我遇到了一个微妙的麻烦情况。我把原型的名称缩短为"rand"。突然间,在一个for (let i in arr)循环中,它迭代了所有预期的索引,并且还迭代了一个"rand"的索引。不得不切换到for (let i=0,l=arr.length;i<l;i++)循环来修复它。 - OXiGEN
1
顺便提一下,我们可以将随机方法添加到数组本身中:items.random=function() {return this[Math.floor(Math.random()*this.length)];}。这样,您可以调用该方法,如 items.random(),而不必涉及对原型的篡改争议。 - Manngo
显示剩余2条评论

133

使用下划线(或者 loDash :)):

var randomArray = [
   '#cc0000','#00cc00', '#0000cc'
];

// use _.sample
var randomElement = _.sample(randomArray);

// manually use _.random
var randomElement = randomArray[_.random(randomArray.length-1)];

或者要打乱整个数组:

// use underscore's shuffle function
var firstRandomElement = _.shuffle(randomArray)[0];

45
只使用underscore或lodash来实现一个函数可能有些大材小用,但如果你在进行复杂的JavaScript功能时,它能够节省数小时甚至数天的时间。 - chim
26
现在下划线也是这个代码更好的选择:_.sample([1, 2, 3, 4, 5, 6]) - Mikael Lepistö
7
在任何真实项目中,你可能会经常使用 _ 。这并不是什么坏事。 - superluminary
9
lodash已在npm上进行了模块化,因此您可以只安装“sample”函数,如果需要的话:https://www.npmjs.com/package/lodash.sample - XåpplI'-I0llwlg'I -
8
我的信条是在任何项目中尽可能少地使用库。话虽如此,我总是最终使用lodash。它实在是太方便了,不用它都不行。 - Phil Andrews
显示剩余4条评论

110

如果你真的必须使用jQuery来解决这个问题(注意:你不应该这样做):

(function($) {
    $.rand = function(arg) {
        if ($.isArray(arg)) {
            return arg[$.rand(arg.length)];
        } else if (typeof arg === "number") {
            return Math.floor(Math.random() * arg);
        } else {
            return 4;  // chosen by fair dice roll
        }
    };
})(jQuery);

var items = [523, 3452, 334, 31, ..., 5346];
var item = jQuery.rand(items);

这个插件可以在给定一个数组时返回随机元素,给定一个数字时返回[0 .. n)范围内的值,对于其他任何给定的内容,都会返回保证随机的值!

为了增加趣味性,当给定一个数组时,通过基于数组长度的递归调用函数来生成随机值 :)

可在http://jsfiddle.net/2eyQX/查看工作演示。


3
@neoascetic 这句话的意思是从数组中选择一个元素不是jQuery的问题,而是通用的JS问题。 - Alnitak
121
公正骰子的加一![为那些没有听懂笑话的可怜人提供帮助。](http://xkcd.com/221/) - The Guy with The Hat
5
肯定的。平均每行不到3个链接方法,并且 $ 在每行至少没有使用一次,因此它没有足够的 jQuery。 - user6560716
2
这不是需要 jQuery 解决的问题。 - robertmain
1
https://needsmorejquery.com/ - easrng
显示剩余4条评论

74

以下是另一种方法:

function rand(items) {
    // "~~" for a closest "int"
    return items[~~(items.length * Math.random())];
}

或者按照以下建议,由@1248177提供:

function rand(items) {
    // "|" for a kinda "int div"
    return items[items.length * Math.random() | 0];
}

48
那个疯狂的 ~~ 是什么?我以前在JS中从未见过它。 - Sam Stern
10
执行搜索,它基本上将操作数转换为最接近的整数。 - Dan Dascalescu
9
实际上,它会向下取整,就像“Math.floor”一样。 - user6560716
20
好的回答。您还可以更简洁一些:items[items.length * Math.random() | 0] :) - aloisdg
17
实际上,它向0四舍五入,即~~(-1.5)会变成-1,而不是Math.floor得到的-2。 - ProfDFrancis
显示剩余4条评论

53
var random = items[Math.floor(Math.random()*items.length)]

25
// 1. Random shuffle items
items.sort(function() {return 0.5 - Math.random()})

// 2. Get first item
var item = items[0]

更短:

var item = items.sort(function() {return 0.5 - Math.random()})[0];

更加简短的版本(由José dB.提供):

let item = items.sort(() => 0.5 - Math.random())[0];

3
items[1] 是第二个项目,第一个是 items[0] - Linus Unnebäck
哦,抱歉。当然是items[0]。 - Ivan Pirog
8
这并不能给你一个均匀的洗牌结果:http://sroucheray.org/blog/2009/11/array-sort-should-not-be-used-to-shuffle-an-array/ - rrauenza
2
下一个射手: let item = items.sort(() => 0.5 - Math.random())[0]; - José dB.
也很好知道该算法的复杂度 :) - Max
函数重新运行时是否有排除当前项的选项? - Mista K.

23

jQuery是JavaScript!它只是一个JavaScript框架。因此,要查找随机项,只需使用纯旧JavaScript,例如:

var randomItem = items[Math.floor(Math.random()*items.length)]

16
var rndval=items[Math.floor(Math.random()*items.length)];

9
var items = Array(523,3452,334,31,...5346);

function rand(min, max) {
  var offset = min;
  var range = (max - min) + 1;

  var randomNumber = Math.floor( Math.random() * range) + offset;
  return randomNumber;
}


randomNumber = rand(0, items.length - 1);

randomItem = items[randomNumber];

来源:

JavaScript函数:随机数生成器


2
FYI,这可以写成一行代码:Math.floor(Math.random() * (max - min + 1)) + min - Solomon Ucko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接