Вопрос:
Я смущен тем, как массивы (в Javascript) работают в тандеме с такими функциями, как math.random. Вот пример кода, который я использовал бы (я прочитал на нескольких сайтах, что math.random не лучший генератор псевдослучайных чисел, но он будет работать для моих целей понимания того, как math.random выбирает переменные в массивах):
var examples= [1, 2, 3, 56, «foxy», 9999, «jaguar», 5.4, «caveman»]; var example= examples[Math.round(Math.random() * (examples.length-1))]; console.log(example);
Когда я помещаю это в журнал консоли, выберите одну из переменных и распечатайте ее там. И поскольку Math.random выбирает число, большее или равное 0, и меньше 1, какое конкретное число присваивается каждой переменной в “примерах var”? Например, какое число будет выбрано, что приведет к печати “1” или “foxy” для распечатки?
Всякая переменная в массиве занимает равное количество длины от большего или равного 0 и меньше 1? Спасибо за помощь и извините, если это сформулировано плохо или нет в правильном формате.
Ответ №1Содержание
- Math.round() vs. Math.floor()
- Сохранение простоты
- Math.random
- Массивы и их индексы
- Длина массива
- Больше случайной математики
- Math.random()
- * mathematics.length – 1
- Выводы первой части
- Наконец
- Дополнительная информация/Источники
Math.round() vs. Math.floor()
Первое, что нужно отметить: Math.round() никогда не будет использовать правильную функцию, когда вы имеете дело со значением, возвращаемым Math.random(). Он должен быть Math.floor() вместо этого, а затем вам не нужна коррекция -1 на length. Это связано с тем, что Math.random() возвращает значение >= 0 и < 1.
Это немного сложно, поэтому давайте рассмотрим конкретный пример: массив с тремя элементами. Как объясняет vihan1086 отличный ответ, элементы этого массива пронумерованы 0, 1 и 2. Чтобы выбрать случайный элемент из этого массива, вы хотите получить равные шансы получить любое из этих трех значений.
Посмотрим, как это работает с Math.round( Math.random() * array.length — 1 ). Длина массива 3, поэтому мы будем умножать Math.random() на 2. Теперь мы имеем значение n, то есть >= 0 и < 2. Мы округлим это число до ближайшего целого числа:
Если n равно >= 0 и < .5, округляется до 0.
Если n – >= .5 и < 1.5, округляется до 1.
Если n равно >= 1.5 и < 2, округляется до 2.
Пока все хорошо. У нас есть шанс получить любое из трех значений, которые нам нужны, 0, 1 или 2. Но каковы шансы?
Посмотрите внимательно на эти диапазоны. Средний диапазон (.5 до 1.5) в два раза длиннее двух других диапазонов (0 до .5 и 1.5 до 2). Вместо равных шансов для любого из трех значений индекса у нас есть 25% -ный шанс получить 0, 50% шанс получить 1 и 25% -ный шанс 2. К сожалению.
Вместо этого нам нужно умножить результат Math.random() на всю длину массива 3, поэтому n есть >= 0 и < 3, а затем вывести этот результат: Math.floor( Math.random() * array.length ) Он работает следующим образом:
Если n – >= 0 и < 1, он доходит до 0.
Если n – >= 1 и < 2, он доходит до 1.
Если n – >= 2 и < 3, он доходит до 2.
Теперь у нас есть равная вероятность попадания в любое из трех значений 0, 1 или 2, потому что каждый из этих диапазонов имеет одинаковую длину.
Сохранение простоты
Вот рекомендация: не пишите весь этот код в одном выражении. Разбейте его на простые функции, которые понятны и понятны. Вот как мне нравится делать эту конкретную задачу (выбор случайного элемента из массива):
// Return a random integer in the range 0 through n — 1 function randomInt( n ) { return Math.floor( Math.random() * n ); } // Return a random element from an array function randomElement( array ) { return array[ randomInt(array.length) ]; }
Тогда остальная часть кода проста:
var examples = [ 1, 2, 3, 56, «foxy», 9999, «jaguar», 5.4, «caveman» ]; var example = randomElement( examples ); console.log( example );
Посмотрите, насколько проще это так? Теперь вам не нужно делать этот математический расчет каждый раз, когда вы хотите получить случайный элемент из массива, вы можете просто вызвать randomElement(array).
Ответ №2
Они довольно часто происходят, поэтому я сломаю их:
Math.random
У вас есть первая часть справа. Math.random будет генерировать число >= 0 и < 1. Math.random может возвращать 0, но шансов почти 0 Я думаю, что это как 1/(16!). Это сделает число, например:
0.6687583869788796
Остановитесь там на секунду
Массивы и их индексы
Каждый элемент массива имеет индекс или позицию. Это колеблется от 0 до бесконечности. В JavaScript массивы начинаются с нуля, а не один. Вот график:
[ ‘foo’, ‘bar’, ‘baz’ ]
Теперь индексы следующие:
name | index ——|—— foo | 0 bar | 1 baz | 2
Чтобы получить элемент из него, используйте []:
fooBarBazArray[0]; // foo fooBarBazArray[2]; // baz
Длина массива
Теперь длина массива будет не такой, как наибольший индекс. Это будет длина, как если бы мы посчитали это. Таким образом, указанный массив вернет 3. Каждый массив имеет свойство length, которое содержит длину:
[‘foo’, ‘bar’, ‘baz’].length; // Is 3
Больше случайной математики
Теперь взглянем на эту случайную вещь:
Math.round(Math.random() * (mathematics.length-1))
Они много идут. Позвольте сломать его:
Math.random()
Итак, сначала мы генерируем случайное число.
* mathematics.length – 1
Целью этого случайного является создание индекса случайных массивов. Нам нужно вычесть 1 из длины, чтобы получить наивысший индекс.
Выводы первой части
Теперь это дает нам число от 0 до максимального массива. На массиве образцов я показал ранее:
Math.random() * ([‘foo’, ‘bar’, ‘baz’].length — 1)
Теперь это небольшая проблема:
Этот код делает случайное число между 0 и длиной. Это означает, что -1 не должно быть. Пусть исправить этот код:
Math.random() * [‘foo’, ‘bar’, ‘baz’].length
Запустив этот код, я получаю:
2.1972009977325797 1.0244733088184148 0.1671080442611128 2.0442249791231006 1.8239217158406973
Наконец
Чтобы получить случайный индекс, мы должны сделать это от уродливого десятичного до хорошего целого числа: Math.floor будет в основном усекать десятичную дробь.
Результаты Math.floor:
2 0 2 1 2
Мы можем поместить этот код в [], чтобы выбрать элемент в массиве при случайном индексе.
Дополнительная информация/Источники
- Случайные номера
- Другие решения
Ответ №3
Вы смотрите на простое умножение и ошибку в коде. Он должен ссылаться на “примеры” массива, которые вы выбираете, вместо того, что вы не упомянули, называется “математика”:
var example = examples[Math.round(Math.random() * (examples.length-1))]; ^^
Затем вы просто умножаете случайное число на количество вещей в массиве. Таким образом, максимальное случайное число равно 1, и если в вашем массиве 50 вещей, вы умножаете случайное число на 50, и теперь максимальное случайное число равно 50.
И все меньшие случайные числа (от 0 до 1) также масштабируются 50x и теперь распространяются от (0 до 50) с примерно одинаковой случайностью с ними. Затем вы округлите его до ближайшего целого числа, которое является случайным индексом в вашем массиве от 1 до n, и вы можете сделать элемент [thatnumber], чтобы выбрать его.
Полные примеры:
Math.random() возвращает числа от 0 до 1 (он может возвращать 0, но вероятность этого невероятно мала):
Math.random() 0.11506261994225964 Math.random() 0.5607304393516861 Math.random() 0.5050221864582 Math.random() 0.4070177578793308 Math.random() 0.6352060229006462
Умножьте эти числа на что-то, чтобы их масштабировать; 1 x 10 = 10 и поэтому Math.random() * 10 = случайные числа между 0 и 10.
Math.random() * n возвращает числа от 0 до n:
Math.random() * 10 2.6186012867183326 Math.random() * 10 5.616868671026196 Math.random() * 10 0.7765205189156167 Math.random() * 10 6.299650241067698
Затем Math.round(number) удаляет десятичные знаки и оставляет ближайшее целое число от 1 до 10:
Math.round(Math.random() * 10) 5
Затем вы выбираете нумерованный элемент:
examples[ Math.round(Math.random() * 10) ];
И вы используете .length-1, потому что индексирование подсчитывается от 0 и заканчивается на длине-1 (см. объяснение @vihan1086, в котором есть много статей об индексировании массива).
Этот подход не очень хорош в случайности – особенно гораздо менее вероятно, чтобы выбрать первый и последний элементы. Я не понял, когда написал это, но ответ @Michael Geary намного лучше – избегая Math.round() и не используя length-1.