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

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), ищите в другом месте. :)

Phrogz
источник
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));

Наслаждайтесь!

Simonbor
источник
Ты прав. Удалил мой комментарий. Исправленная версия актуального кратчайшего пути: [... 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 ().

Лахлан Хант
источник
1

См. Ниже: -

let arr = Array.apply(null, {length: 1000}).map(Function.call, Math.random)
/* will create array with 1000 elements */
Авадхут Торат
источник
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);
Джейми337николс
источник
"почти уверен", как насчет использования 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)];
brbn
источник