创建一个具有随机值的数组


Answers:


53

这是一种解决方案,它可以打乱唯一编号的列表(永远不会重复)。

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

// http://stackoverflow.com/questions/962802#962890
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);

如果要允许重复的值(这不是OP想要的值),请在其他地方查找。:)


4
如果数字应该唯一,则此解决方案很好,但这是完全不同的统计/概率问题。我希望这对于OP来说是清楚的,并且与他们的情况无关,但是在某些情况下,这可能会对程序的正确性产生重大影响。(我不是在批评答案,只是在为将来的读者升旗。您可能想提一下。)另请参见:en.wikipedia.org/wiki/Combination(“有”或“无重复”之间的区别
chiccodoro

var random_array = new Array(40).fill()。map((a,i)=> a = i).sort(()=> Math.random()-0.5); 我认为这与上述相同
Jamie337nichols 19/09/16

如何将其排除在生成数字0之外?
Gosi

208

最短的方法(ES6)

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

请享用!


你是对的。删除了我的评论。实际最短方法的更正版本:[... Array(20)]。map(()=> {返回Math.floor(Math.random()* 30)});
jaheraho

7
如果我们从答案的方法中删除空格,则比您建议的字符少4个字符。当然,如果您对打高尔夫球感兴趣,那么实际上您就省略了一些简单的字符切割快捷方式:[...Array(40)].map(_=>Math.ceil(Math.random()*40));将比您的字符少11个字符,比原始字符少7个字符。
凯尔·贝克

(校正速度不够快-如果使用Math.ceil,则必须为* 39才能满足OP的标准,尽管我们将0切除为一个选项。如果我们可以接受1-40而不是0-39,则可以使用。否则,请减少回溯的改进时间Math.floor
凯尔·贝克

优秀!感谢您的分享
Adriel Werlich

43

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也是当前索引。没错,在两种情况下它们都是不必要的。您可以根据需要删除它们。
尤金·库拉布霍夫

1
我不知道您认为ES6的版本在哪里工作?Array.from作品...这是您的代码示例... randomArray =(长度:数字,最大:数字)=> Array.from({length}).map(()=> Math.floor(Math .random()* max));
基督教马修

31

更短的ES6方法:

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

另外,您可以使用带有参数的函数:

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

1
.fill()需要一个值参数
Damian Green

4
@DamianGreen- .fill()没有任何参数将使用填充数组undefined,这是这里唯一需要.map()工作的东西
vsync

@Damjan有没有办法不重复数字?喜欢这种方法
Henrique

@Henrique使用变量?🤔–塞比
Sebj)

@Sebj有可能吗?我的意思是,任何像这样的短方法,以及使用道具作为长度和最大长度的方法,对我来说都是完美的:)
Henrique


16

Math.random()将返回0到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,而不是数字1。字体很难分辨。
Mu Mind

11

..我得到的数组很少是随机的。它会产生很多连续数字的方块...

随机项目的序列通常包含连续的数字块,请参阅“ 赌徒的谬误”。例如:

..我们刚刚连续扔了四个脑袋..由于连续五个脑袋运行的概率仅为1⁄32 ..受赌徒谬论的人可能会认为,下一次翻转的可能性小于成为尾巴。 http://en.wikipedia.org/wiki/Gamblers_fallacy


+1。人们需要决定是需要真实的(统计上的)随机数还是需要“看起来随机”的数。
chiccodoro

4

由于数字范围受到限制,我想说的最好的方法是生成数组,将数字从0到39(按顺序)填充,然后将其随机播放。



我不知道他想要每个数字,而是完全随机的吗?如果他对随机顺序,静态值没问题,那么它将正常工作。
罗伯特

可能会完成这项工作,但与使用Math.random()40次相比,结果会略有不同,因为它将强制每个数字出现一次且不会重复。
Mu Mind

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

将数组限制为6个值,以便于查看。


3
var myArray = [];
var arrayMax = 40;
var limit = arrayMax + 1;
for (var i = 0; i < arrayMax; i++) {
  myArray.push(Math.floor(Math.random()*limit));
}

上面是传统的方法,但是如果您想避免数组中的重复而不必执行昂贵的计算,那么我会使用@Pointy和@Phrogz


3

每天都有古怪的单行解决方案。

数组中的值是完全随机的,因此当您使用此代码段时,它将有所不同。

小写随机字符的数组(长度为10)

Array.apply(null, Array(10)).map(function() { return String.fromCharCode(Math.floor(Math.random() * (123 - 97) + 97)); })

['k','a','x','y','n','w','m','q','b','j']

数组(长度为10),其随机整数范围为0到99

Array.apply(null, Array(10)).map(function() { return Math.floor(Math.random() * 100 % 100); })

[86,77,83,27,79,96,67,75,52,21]

数组随机日期(从10年前到现在)

Array.apply(null, Array(10)).map(function() { return new Date((new Date()).getFullYear() - Math.floor(Math.random() * 10), Math.floor(Math.random() * 12), Math.floor(Math.random() * 29) )})

[2008-08-22T21:00:00.000Z,2007-07-17T21:00:00.000Z,
2015-05-05T21:00:00.000Z,2011-06-14T21:00:00.000Z,
2009-07-23T21 :00:00.000Z,2009-11-13T22:00:00.000Z,
2010-05-09T21:00:00.000Z,2008-01-05T22:00:00.000Z,
2016-05-06T21:00:00.000Z, 2014-08-06T21:00:00.000Z]

数组(长度为10)的随机字符串

Array.apply(null, Array(10)).map(function() { return Array.apply(null, Array(Math.floor(Math.random() * 10  + 3))).map(function() { return String.fromCharCode(Math.floor(Math.random() * (123 - 97) + 97)); }).join('') });

['cubjjhaph','bmwy','alhobd','ceud','tnyullyn','vpkdflarhnf,'hvg','arazuln','jzz','cyx']

您可能会在这里找到其他有用的东西https://github.com/setivolkylany/nodejs-utils/blob/master/utils/faker.js


1

使用一些新的ES6功能,现在可以使用以下方法实现:

function getRandomInt(min, max) {
    "use strict";
    if (max < min) {
        // Swap min and max
        [min, max] = [min, max];
    }

    // Generate random number n, where min <= n <= max
    let range = max - min + 1;
    return Math.floor(Math.random() * range) + min;
}

let values = Array.from({length: 40}, () => getRandomInt(0, 40));

console.log(values);

请注意,此解决方案仅在支持以下ES6功能的现代浏览器中起作用:箭头函数和Array.from()。



0

从@Phrogz建议的页面

for (var i=0,nums=[];i<49;i++) nums[i]={ n:i, rand:Math.random() };
nums.sort( function(a,b){ a=a.rand; b=b.rand; return a<b?-1:a>b?1:0 } );

0

我需要的东西与这些解决方案所提供的东西有所不同,因为我需要创建一个数组,其中将多个不同的随机数保持在指定范围内。下面是我的解决方案。

function getDistinctRandomIntForArray(array, range){
   var n = Math.floor((Math.random() * range));
   if(array.indexOf(n) == -1){        
    return n; 
   } else {
    return getDistinctRandomIntForArray(array, range); 
   }
}

function generateArrayOfRandomInts(count, range) {
   var array = []; 
   for (i=0; i<count; ++i){
    array[i] = getDistinctRandomIntForArray(array, range);
   };
   return array; 
}

我希望不要创建一个循环,该循环有可能导致大量不必要的调用(如果您的计数和范围很高并且接近相同的数字),但这是我能想到的最好的循环。


0
function shuffle(maxElements) {
    //create ordered array : 0,1,2,3..maxElements
    for (var temArr = [], i = 0; i < maxElements; i++) {
        temArr[i] = i;
    }

    for (var finalArr = [maxElements], i = 0; i < maxElements; i++) {
        //remove rundom element form the temArr and push it into finalArrr
        finalArr[i] = temArr.splice(Math.floor(Math.random() * (maxElements - i)), 1)[0];
    }

    return finalArr
}

我猜想这种方法将解决概率问题,仅受随机数生成器限制。


0

如果您需要从0 ...长度范围内随机唯一的值:

const randomRange = length => {
  const results = []
  const possibleValues = Array.from({ length }, (value, i) => i)

  for (let i = 0; i < length; i += 1) {
    const possibleValuesRange = length - (length - possibleValues.length)
    const randomNumber = Math.floor(Math.random() * possibleValuesRange)
    const normalizedRandomNumber = randomNumber !== possibleValuesRange ? randomNumber : possibleValuesRange

    const [nextNumber] = possibleValues.splice(normalizedRandomNumber, 1)

    results.push(nextNumber)
  }

  return results
}

randomRange(5) // [3, 0, 1, 4, 2]

0

我很确定这是创建随机数组而不重复的最短方法

var random_array = new Array(40).fill().map((a, i) => a = i).sort(() => Math.random() - 0.5);

“相当肯定”,如何使用keys功能:Array.from(Array(40).keys()).sort(_ => Math.random() - .5)?您甚至可能会发疯,并使用传播运算符!但这对我来说太令人兴奋了。
雪人

0

晚会晚了一点,但是我使用randojs.com来保证随机性,因为它使这种超级简单的事情变得容易。您可以像这样从0到39随机获得一组数字数组:

console.log(randoSequence(40));
<script src="https://randojs.com/1.0.0.js"></script>

不用为它的物流而烦恼-再加上它的可读性强和易于理解:)


0

发电机

如@Phrogz和@Jared Beck所解释的,长度为40的40个随机可能值(0-39)的数组不重复值最好改组它。仅用于记录的另一种方法可能是使用生成器。但是与其他提议的解决方案相比,这种方法缺乏性能

function* generateRandomIterable(n, range) {
  for (let i = 0; i < n; i++) {
    yield ~~(Math.random() * range);
  }
}
const randomArr = [...generateRandomIterable(40,40)];
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.