Создать массив со случайными значениями


101

Как я могу создать массив из 40 элементов со случайными значениями от 0 до 39? подобно

[4, 23, 7, 39, 19, 0, 9, 14, ...]

Я пробовал использовать решения отсюда:

http://freewebdesigntutorials.com/javaScriptTutorials/jsArrayObject/randomizeArrayElements.htm

но массив, который я получаю, очень мало рандомизирован. Он генерирует множество блоков последовательных чисел ...

Ответы:


54

Вот решение, которое перемешивает список уникальных номеров (без повторов).

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
Это решение хорошо, если числа должны быть уникальными, но это совершенно другая статистическая / вероятностная вещь. Я надеюсь, что это было ясно для ОП и не имело отношения к их делу, но в некоторых случаях это может иметь большое влияние на правильность программы. (Я не критикую ответ, просто поднимаю флаг для будущих читателей. Вы можете упомянуть об этом.) См. Также: en.wikipedia.org/wiki/Combination (различие между «с» и «без повторения»
— chiccodoro

var random_array = новый массив (40) .fill (). map ((a, i) => a = i) .sort (() => Math.random () - 0.5); Я думаю, что это то же самое, что и выше
— Jamie337nichols

Как исключить его из генерации числа 0?
— Gosi

210

Самый короткий подход (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

7
Если мы удалим пробелы из подхода к ответу, это на 4 символа меньше, чем тот, который вы предложили. Конечно, если вы заинтересованы в игре в гольф, вы фактически упустили несколько простых способов сокращения персонажей: [...Array(40)].map(_=>Math.ceil(Math.random()*40));было бы на 11 символов меньше вашего и на 7 меньше, чем в оригинале.
— Кайл Бейкер

(было недостаточно быстро для исправления - должно быть * 39, чтобы соответствовать критериям OP, если мы используем Math.ceil, хотя мы исключили 0 как вариант. Если мы можем принять 1-40 вместо 0-39, это сработает. В противном случае , уменьшите улучшение персонажа для возврата к Math.floor)
— Кайл Бейкер

45

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 = (length: number, max: number) => Array.from ({length}) .map (() => Math.floor (Math .random () * макс));
— Кристиан Мэтью

32

Еще более короткий подход 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 использует переменные? 🤔
— Sebj

@Sebj это возможно? Я имею в виду, что любой подход, такой как этот, и с реквизитами в качестве длины и максимума, идеально подойдет для меня :)
— Энрике

32

Самый короткий :-)

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


20
~~сокращение от Math.floor
— Курт

1
это круто; есть ли широкая поддержка этого ~~сокращения? (править: ааа, я вижу , это просто побитовый оператор )
— Рэйф Голдберг,

@Curt только для положительных чисел
— AJ Uppal

1
К сожалению, это не «краткий» ответ. Он ответил с улыбкой.
— OXiGEN

@AJUppal OP попросил конкретный пример 0-39, так что просто уйду
— Курт

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, а не цифра 1, в «l = 40», «i <l» и «Math.random () * l». По шрифту сложно сказать.
— Mu Mind

11

.. получаемый мной массив очень мало рандомизирован. Он генерирует множество блоков последовательных чисел ...

Последовательности случайных элементов часто содержат блоки последовательных чисел, см. «Заблуждение игрока» . Например:

.. мы только что подбросили четыре орла подряд .. Так как вероятность выпадения пяти следующих друг за другом орлов составляет всего 1/32 .. человек, подверженный заблуждению игрока, может подумать, что следующий бросок с меньшей вероятностью будет орлом, чем быть решками. http://en.wikipedia.org/wiki/Gamblers_fallacy


+1 точно. Нужно решить, нужны ли ему реальные (статистически) случайные числа или числа, которые «выглядят случайными».
— chiccodoro

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

ограничил массив до 6 значений, чтобы было легче увидеть.


4

Поскольку диапазон чисел ограничен, я бы сказал, что лучше всего создать массив, заполнить его числами от нуля до 39 (по порядку), а затем перетасовать его.



Я не знаю, что ему нужно было каждое число между ними, но скорее оно было случайным? Если он в порядке со случайным порядком, статическими значениями, тогда это сработает.
— Роберт

который может сработать, но даст несколько другие результаты, чем если бы вы использовали Math.random()40 раз, поскольку он заставит каждое число появляться один раз и не будет повторяться.
— Mu Mind

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

Генераторы

Массив длиной 40 из 40 случайных возможных значений (0 - 39) без повторяющихся значений лучше перемешать, как объясняют @Phrogz и @Jared Beck. Другой подход, только для записей, может заключаться в использовании генераторов. Но такому подходу не хватает производительности по сравнению с другими предлагаемыми решениями .

function* generateRandomIterable(n, range) {
  for (let i = 0; i < n; i++) {
    yield ~~(Math.random() * range);
  }
}
const randomArr = [...generateRandomIterable(40,40)];
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.