创建一个包含随机值的数组。

170
24个回答

375

最短的方法(ES6):

// randomly generated N = 40 length array 0 <= A[N] <= 39
Array.from({length: 40}, () => Math.floor(Math.random() * 40));

你是对的。我删除了我的评论。这是实际最短方式的修正版本:[...Array(20)].map(()=>{return Math.floor(Math.random()*30)}); - jaheraho
18
如果我们从答案方法中去除空格,它比你提出的方法少了4个字符。当然,如果你对高尔夫感兴趣,实际上有一些简单的字符削减快捷方式被省略了:[...Array(40)].map(_=>Math.ceil(Math.random()*40)); 比你的方法少11个字符,比原来的方法少7个字符。 - Kyle Baker
没有足够快地进行更正 - 如果我们使用 Math.ceil,则需要*39才能满足OP的要求,尽管我们将0作为一个选项剔除了。如果我们可以接受1-40而不是0-39,则可以这样做。否则,回到 Math.floor 将减少一个字符的改进。 - Kyle Baker

69

下面是一种解决方案,可以打乱一个列表中的唯一数字(永远不会重复)。

for (var a=[],i=0;i<40;++i) a[i]=i;

// https://dev59.com/WHNA5IYBdhLWcg3wcNXF
function shuffle(array) {
  var tmp, current, top = array.length;
  if(top) while(--top) {
    current = Math.floor(Math.random() * (top + 1));
    tmp = array[current];
    array[current] = array[top];
    array[top] = tmp;
  }
  return array;
}

a = shuffle(a);

如果你想允许重复的值(这不是问题提出者想要的),那么请寻找其他方法。 :)


5
如果数字需要唯一性,那么此解决方案是不错的选择,但这完全是一个不同的统计/概率问题。我希望这对楼主来说很清楚,并且在他们的情况下没有相关性,但在某些情况下,它可能对程序的正确性产生重大影响。(我不是在批评答案,只是为未来的读者发出警示。你可能需要提到这一点。)另请参见:https://en.wikipedia.org/wiki/Combination(“有”或“无重复”的区别)。 - chiccodoro
1
var random_array = new Array(40).fill().map((a, i) => a = i).sort(() => Math.random() - 0.5); 我认为这与上面的代码相同。 - Jamie337nichols
如何排除生成数字0? - Gosi
这是一个ES6版本,它允许您在最小/最大值方面具有一定的灵活性,但仍然可以为您提供唯一数字的数组:http://pastie.org/p/069IAzSzsRhN6JXdAIpPhc - Curt

60

最短的:

[...Array(40)].map(e=>~~(Math.random()*40))

49
“~~” 是 Math.floor 的简写。 - Curt
1
这很棒;那个 ~~ 简写有广泛的支持吗?(编辑:啊,它只是一个位运算符,我明白了) - Rafe Goldberg
@Curt 仅适用于正数。 - A.J. Uppal
1
遗憾的是,这不是一个“简短”的答案。他微笑着回答道。 - OXiGEN
@A.J.Uppal,原帖要求提供0-39的具体示例,因此我们就以此为基础。 - Curt
1
@RafeGoldberg 是的,它是一个位运算符。另一个等价的写法是XXX | 0,但我觉得~~更加简洁。 - Curt

53

ES5:

function randomArray(length, max) {
    return Array.apply(null, Array(length)).map(function() {
        return Math.round(Math.random() * max);
    });
}

ES6:

randomArray = (length, max) => [...new Array(length)]
    .map(() => Math.round(Math.random() * max));

1
“_”和“i”参数怎么了?除非我弄错了,在ES6中是不必要的。 - AfricanMatt
2
@AfricanMatt,_是当前元素,i是当前索引。你说得对,在这两种情况下都是不必要的。如果你愿意,可以将它们删除。 - Eugene Kulabuhov
2
我不知道你认为ES6版本在哪里起作用?Array.from可以使用...这里有一个使用你的代码的例子...randomArray = (length: number, max: number) => Array.from({length}) .map(() => Math.floor(Math.random() * max)); - Christian Matthew
@EugeneKulabuhov 为什么你要写 [...new Array(length)],而不是直接写 new Array(length) 呢? - Magne
这就是我一直在寻找的。 - Ariful Islam

49

ES6更简短的方法:

Array(40).fill().map(() => Math.round(Math.random() * 40))

此外,您可以创建一个带参数的函数:

const randomArray = (length, max) => 
  Array(length).fill().map(() => Math.round(Math.random() * max))

3
.fill() 需要一个值参数。 - Damian Green
9
.fill()方法不带参数时,会用undefined填充数组,在这里使用.map()时只需要这个就可以了。 - vsync
@Damjan有没有不重复数字的方法?我喜欢这个做法。 - Henrique
@Henrique 使用变量? - Sebj
@Sebj 这个可能吗?我的意思是,如果有一个像这样简短的方法,并且使用长度和最大值作为参数,那对我来说就完美了 :) - Henrique

17

Math.random()会返回一个介于0和1(不包括1)之间的数字。因此,如果您想要0-40之间的数字,可以将其乘以40,结果可能的最大值就是您所乘的数字。

var arr = [];
for (var i=0, t=40; i<t; i++) {
    arr.push(Math.round(Math.random() * t))
}
document.write(arr);

http://jsfiddle.net/robert/tUW89/


1
澄清一下:在“l = 40”,“i < l”和“Math.random() * l”中,“l”是字母L,不是数字1。字体让人难以分辨。 - Mu Mind

12
const randomNumber = Array.from({length: 6}, () => Math.floor(Math.random() * 39));

将数组限制为6个值以便更容易查看。


11

我得到的数组很少随机化。 它生成了许多连续数字块...

随机项序列经常包含连续数字块,参见赌徒谬误。例如:

..我们刚刚抛出了四个正面朝上的硬币..由于五个连续正面朝上的概率仅为1⁄32..一个受到赌徒谬误影响的人可能会认为下一次翻转比翻转尾巴更不可能是正面。 http://en.wikipedia.org/wiki/Gamblers_fallacy


+1 确切地说,一个人需要决定是否需要真正(统计上)的随机数,还是看起来像随机的数字。 - chiccodoro

10

由于*|的优先级更高,因此可以使用|0代替Math.floor()来缩短代码。

[...Array(40)].map(e=>Math.random()*40|0)

超级简洁,喜欢它 - King Friday

8

您只需要两行代码就可以生成包含10个随机数字的数组。

let result = new Array(10)
result = result.fill(0).map(() => Math.random());

and just .

console.log(vals);

1
让 r = [...Array(40)].map(_=>Math.random()*40|0)(更短,符合 OP 的需求) - vdegenne

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