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

Безусловно, можно использовать какую-нибудь библиотеку, но, так как создание такой генерации не слишком сложно и не займет много строк кода, было бы неплохо написать ее самому.

Для генерации контента нам понадобятся три функции и источник самих слов:

  1. Функция, возвращающая случайное число.

  2. Функция, которая предоставляет нам случайное слово.

  3. Функция, которая делает из слов полноценную строку.

  4. Источник слов в виде массива строк (можно взять из моего Github Gist).


1. Генерация случайного числа

Так как мы хотим получить случайное слово из нашего массива, нам надо генерировать случайный индекс. С учетом этого, следует помнить о минимальном и максимальном значении индекса массива.

Math.random();
// Returns 0.534098468876492

С помощью функции Math.random() мы получаем дробное число от 0 до 1 (не включая 1). Когда мы умножаем его, например, на 10, то получаем число от 0 до 10 (также не включая верхнюю границу). Но в нашем случае, нам хочется получить число от 0 до 10, включая верхнюю границу.

Math.random() * (10 - 0) + 0;
// Returns 8.448742196214798

Но сейчас мы все еще получаем дробное число. Мы должны использовать Math.round, чтобы сделать его целым.

Math.round(Math.random() * (10 - 0) + 0)
// Returns 6 or 5 or 9 or 10

Благодаря этим вычислениям мы получаем целое число от 0 до 10, включая обе границы. Вы также можете протестировать этот код.

let number = 0;
let steps = 0;
while(number != 10) {
    number = Math.round(Math.random() * (10 - 0) + 0);
    steps = steps + 1;
    console.log('steps', steps)
}

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

function randomNumber(min, max) {
    return Math.round(Math.random() * (max - min) + min);
}

Это финальная функция получения случайного числа в диапазоне. Давайте продолжим и сделаем функцию получения случайного слова из массива.


2. Получение случайного слова

Я нашел хорошую коллекцию слов, которую можно использовать. Вы также можете найти ее на Github Gist. В этой статье я буду использовать лишь часть.

const word = [
    "Got",
    "ability",
    "shop",
    "recall",
    "fruit",
    "easy",
    "dirty",
    "giant",
    "shaking",
    "ground",
    "weather",
    "lesson",
    "almost",
    "square",
    "forward",
    "bend",
    "cold",
    "broken",
    "distant",
    "adjective."
]

Будем использовать randomNumber функцию, которую мы сделали на предыдущем шаге. Для получения случайного числа нам необходимо задать диапазон следующим образом.

const word = words[randomNumber(0, words.length - 1)];

Нижняя граница это 0, потому что индексы в массивах начинаются с 0. Верхняя граница легко вычисляется какwords.length - 1 . Мы задаем ее таким образом, потому что в нашем случае в массиве хранятся 20 слов, поэтому words.length вернет 20. Но по ранее упомянутой причине (индексы в массиве начинаются с 0), чтобы получить индекс последнего элемента, необходимо отнять 1.

function getRandomWord() {
    return words[randomNumber(0, words.length - 1)];
}

Итак, мы имеет вторую функцию, которая возвращает случайное слово.


3. Получение строки со случайными словами

Сейчас мы хотим получить несколько слов и сделать из них строку. Лучшим решением будет создать массив из 10 элементов.

[...Array(10)]
// Returns [undefined, undefined, ....] with 10 items

Используя .map метод, мы можем пройтись по массиву и для каждого элемента сгенерировать случайное слово.

[...Array(10)].map(() => getRandomWord())
// Returns ["hand", "close", "ship", "possibly", "metal", "myself", "everybody", "serious", "adult", "favorite"]

В данный момент у нас есть просто массив случайных слов, но чтобы сделать его строкой, мы должны разделить элементы пробелом. Это можно сделать методом .join('').

[...Array(10)].map(() => getRandomWord()).join('')

Также мы хотим добавить читабельности нашей строке, а именно сделать первое слово с заглавной буквы. Давайте обновим функцию getRandomWord .

function getRandomWord(firstLetterToUppercase = false) {
    const word = words[randomNumber(0, words.length - 1)];
    return firstLetterToUppercase ? word.charAt(0).toUpperCase() + word.slice(1) : word;
}

Теперь создадим функцию generateWords . Теперь в getRandomWord(i === 0) будем передавать сравнение индекса с 0, чтобы сделать первое слово (чей индекс как раз равен 0) заглавным.

function generateWords(length = 10) {
    return [...Array(length)].map((_, i) => getRandomWord(i === 0)).join(' ').trim() + '.';
}

4. Завершение

Мы написали все функции, так что можем посмотреть на весь код.

const word = [
    "Got",
    "ability",
    "shop",
    "recall",
    "fruit",
    "easy",
    "dirty",
    "giant",
    "shaking",
    "ground",
    "weather",
    "lesson",
    "almost",
    "square",
    "forward",
    "bend",
    "cold",
    "broken",
    "distant",
    "adjective."
]
function getRandomWord(firstLetterToUppercase = false) {
    const word = words[randomNumber(0, words.length - 1)];
    return firstLetterToUppercase ? word.charAt(0).toUpperCase() + word.slice(1) : word;
}
function generateWords(length = 10) {
    return [...Array(length)].map((_, i) => getRandomWord(i === 0)).join(' ').trim() + '.';
}
function randomNumber(min, max) {
    return Math.round(Math.random() * (max - min) + min);
}

Протестировать его можно на Runkit.

Спасибо за внимание.

Комментарии (8)


  1. dopusteam
    20.02.2022 08:15

    С помощью функции Math.random() мы получаем дробное число от 0 до 1 (не включая 1). Когда мы умножаем его, например, на 10, то получаем число от 0 до 10 (также не включая верхнюю границу). Но в нашем случае, нам хочется получить число от 0 до 10, включая верхнюю границу.

    Math.random() * (10 - 0) + 0;

    минус ноль плюс ноль ничего не изменит


    1. assembled
      20.02.2022 21:35

      Чувак, видимо, нашёл выражение

      Math.random() * (max - min) + min;

      и заменил max и min на свои))

      Человек-препроцессор


  1. PahanMenski
    20.02.2022 08:23
    +4

    У вас вероятность получить 0 или 10 в два раза меньше, чем вероятность получить любое число от 1 до 9. Равновероятное распределение можно получить, например, как:

    Math.floor(Math.random() * 11)


  1. neword
    20.02.2022 11:41

    со рэндомными словами как-то не совсем валидно выглядит :) проще взять списки готовых коротких фраз. например пословицы-поговорки... я заюзал опусы козьмы пруткова :) и лурковские определения коня в сферическом вакууме


  1. kahi4
    20.02.2022 15:07

    1. Перевод? Перевод статьи о том как выбрать случайный элемент из массива? (Остальное - мишура) серьезно?

    2. С такой постановкой задачи можно сделать проще: const selectRandomElementFromArray = (array) => array[~~(Math.random() * array.length)]

    3. Почему строчка выше сработает - домашнее задание

    4. По делу: Loren ipsum не является набором случайных слов и выполняет слегка другую задачу, а именно: генерировать бессмысленный, но правдоподобный текст. Случайные слова будут выделяться и бросаться в глаза, отвлекая от прототипирования и других задач. Чтобы делать правдоподобный текст, нужно значительно заморочиться с грамматикой, выбирать слова в порядке, в каком они могут быть, чтобы у вас не было висячих предлогов, субъекта после объекта, чтобы присутствовал глагол и прочее и был шанс получить сложносочиненные предложения. В целом не очень то-то сложно, но уже не три строки на js


    1. kahi4
      20.02.2022 15:14
      +1

      По поводу правдоподобности данных: не экспериментировал с текстом, но пробовал с датами и временем, так вот 14:67 дня или 43 февраля очень быстро бросается в глаза и все обращают на это внимание потому что мы время / дату видим постоянно и быстро замечаем что что-то не так. Полагаю, три подряд повторяющихся слова так же привлекут внимание.


    1. unsignedchar
      20.02.2022 23:37

      значительно заморочиться с грамматикой

      Собрать пару десятков шаблонов предложений. Разобрать их согласно правилам грамматики (подлежащее, сказуемое, etc). Упаковать в массив, обмазать random'ами ;) Всё достаточно механически.


      1. kahi4
        21.02.2022 12:11

        Так и есть, особенно в английском не очень много возможных порядков слов, но это все равно уже не десять случайных слов с array.join()