Створіть масив із випадковими значеннями


100

Як я можу створити масив із 40 елементів із випадковими значеннями від 0 до 39? Подібно до

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

Я спробував використовувати рішення звідси:

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

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

Відповіді:


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);

Якщо ви хочете дозволити повторювані значення (а це не те, що хотів ОП), тоді шукайте деінде. :)


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

208

Найкоротший підхід (ES6)

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

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


Ти правий. Видалено мій коментар. Виправлена ​​версія фактично найкоротшого шляху: [... масив (20)]. Map (() => {повернути Math.floor (Math.random () * 30)});
jaheraho

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

(не досить швидко, щоб виправити - має бути * 39, щоб відповідати критеріям ОП, якщо ми використовуємо Math.ceil, хоча ми вирізали 0 як варіант. Якщо ми можемо прийняти 1-40 замість 0-39, це працює. Інакше , зменшити характер покращення для повернення до Math.floor)
Kyle Baker

відмінник !!! дякую за обмін
Адріель Верліх

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 . випадковий () * 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 з використанням змінних? 🤔
Себж

@Sebj це можливо? Я маю на увазі, будь-який такий короткий підхід і з реквізитом як довжина і макс ідеально підійдуть мені :)
Анріке


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,
06.05.2016T21: 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 та @Jred 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.