'How to filter vowel and consonant letters generated from a random string
I am making a word game that picks 8 random letters from the alphabet and the player must find words that use these letters. I must find out a way to make the letters picked always contain 3 vowels and 5 consonants. I would appreciate your help
Here is the code I am using to pick the random letters for the game
function makeid(length) {
var result = '';
var characters = 'aaabcdeeefghiiijklmnooopqrstuuuvwxyz';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
let letter = characters.charAt(Math.floor(Math.random() * charactersLength));
while (result.match(letter)) {
letter = characters.charAt(Math.floor(Math.random() * charactersLength));
}
result += letter;
}
return result;
}
console.log("Id of 8 characters", makeid(8))
Solution 1:[1]
@Lars answer is almost perfect, the only problem is that the final string is not truly shuffled.
I suggest you just create two arrays: random vowels and random consonants and then just shuffle them using Fisher-Yates' algorithm.
function getRandomCharsFromString(str, length) {
return Array.from({length}, () => {
return str[Math.floor(Math.random() * str.length)]
});
}
function shuffle(str) {
var a = str.split(""),
n = a.length;
for (var i = n - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
// Swap them with ES6 destructuring magic
[a[i], a[j]] = [a[j], a[i]];
}
return a.join("");
}
function getRandomString() {
const vowels = 'aeiou';
const consonants = 'bcdfghjklmnpqrstvwxyz';
const randomVowels = getRandomCharsFromString(vowels, 3);
const randomConsonants = getRandomCharsFromString(consonants, 5);
const randomWord = [...randomVowels, ...randomConsonants].join('')
return shuffle(randomWord)
}
console.log('random string:', getRandomString())
No repeated letters
You mentioned you don't want repeated letters; many words in English have duplicate letters. Why is that a requirement?
You can shuffle the vowels
and consonants
and get the first x
characters from that string.
// This version makes sure characters are not repeated
function getRandomCharsFromString(str, length) {
return shuffle(str).slice(0, length);
}
function shuffle(str) {
var a = str.split(''),
n = a.length;
for (var i = n - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
// Swap them with ES6 destructuring magic
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
function getRandomString() {
const vowels = 'aeiou';
const consonants = 'bcdfghjklmnpqrstvwxyz';
const randomVowels = getRandomCharsFromString(vowels, 3);
const randomConsonants = getRandomCharsFromString(consonants, 5);
const randomWord = [...randomVowels, ...randomConsonants].join('')
return shuffle(randomWord).join('')
}
console.log('random string:', getRandomString())
Solution 2:[2]
It's a lot of code, but this works for me.
The function begins with a for-loop, which generates 8 different letters. inside of that loop, Math.random() makes it a 37.5% chance that a vowel will be added to the randomArray, and 62.5% that a consonant will be added (8 characters from which 3 are vowels, so 3 / 8 = 0.375).
when that is done 8 times (cuz of the for loop), the array will be turned into a string, and the function will return the string (which is by then an 8-digit letter code with 3 vowels and 5 consonants).
I hope this explanation helps(;
function getRandomString() {
const vowels = 'aeiou'
const consonants = 'bcdfghjklmnpqrstvwxyz'
let randomArray = []
let amountOfVowels = 0
let amountOfConsonants = 0
for (let i = 0; i < 8; i++) {
if (Math.random() < 0.375 && amountOfVowels < 3) addVowel()
else if (amountOfConsonants < 5) addConsonant()
else addVowel()
}
function addVowel() {
randomArray.push(vowels[Math.floor(Math.random() *
vowels.length)])
amountOfVowels++
}
function addConsonant() {
randomArray.push(consonants[Math.floor(Math.random() *
consonants.length)])
amountOfConsonants++
}
let finalString = ''
for (let i = 0; i < 8; i++) {
finalString += randomArray[i]
}
return finalString;
}
console.log('random string:', getRandomString())
Solution 3:[3]
Have one array of consonants and one array for vowels.
Use a shuffling function, here's a terse one liner:
const shuffle = array => array.sort(() => Math.random() - 0.5);
The function above will return a given array in a random order, so you'll need to shorten each array by 5 (
consonants
) and 3 (vowels
):let C = shuffle(consonants); let V = shuffle(vowels); C.length = 5; V.length = 3;
Easy ?
// Utility Function (optional)
const log = data => console.log(JSON.stringify(data));
const consonants = ["B", "C", "D", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "V", "W", "X", "Y", "Z"];
const vowels = ["A", "E", "I", "O", "U"];
const shuffle = array => array.sort(() => Math.random() - 0.5);
let C = shuffle(consonants);
let V = shuffle(vowels);
C.length = 5;
V.length = 3;
const result = shuffle(V.concat(C));
log(result);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 |