Checking user input against an array, act as a guess Javascript - javascript

I am a new aspiring dev and I am trying to figure out how to build a game of hangman using vanilla js only. I have put together a key event listner, and have got it to console log the inputs. I have also got it to print the letters pushed into a "letters guessed" array.
document.addEventListener("keypress", letterPressed);
function letterPressed(event) {
var letter = String.fromCharCode(event.keyCode);
guessedLetters.push(letter);
document.getElementById("lettersGuessed").innerHTML = guessedLetters;
console.log(guessedLetters)
}
I also have an array of choices of words
var wordList = ["Ravens", "Cardinals", "Falcons", "Bills",
"Panthers", "Bears", "Bengals", "Browns", "Cowboys",
"Broncos", "Lions", "Packers", "Texans", "Colts",
"Jaguars", "Cheifs", "Chargers", "Rams",
"Dolphins", "Vikings", "Patriots", "Saints",
"Giants", "Jets", "Raiders", "Eagles", "Steelers",
"Forty Niners", "Seahawks", "Buccaneers", "Titans",
"Redskins"];
and a for loop picking the random word from this array, converting it to "_" strings in the length of the word, and printing it to the html document in a div id of "spaces".
var wordBlanks = [];
var guessedLetters = [];
var randomWord = wordList[Math.floor(Math.random() * wordList.length)];
for (var i = 0; i < randomWord.length; i++) {
wordBlanks[i] = "_";
console.log(wordBlanks,randomWord);
document.getElementById("spaces").innerHTML = wordBlanks.join(" ");
};
Where would I even want to go from here? I want to check input from the keystrokes (or the letters guessed array, im not sure which would be best) against the word thats chosen and have the "_" strings reveal the correct guesses when guessed correctly.
My question is more regarding pointing me in the right direction. So, I can properly teach myself. Any words of advice?
Thank you!

You'll have to come to terms with the upper/lowercase issue first, but after that, something like this will work:
const randomWord = "BEARS";
const guessedLetters = ["S", "O", "E"];
const wordBlanks = randomWord.split('')
.map(letter => guessedLetters.indexOf(letter) >= 0 ? letter : "_")
.join(' ');
console.log(wordBlanks);

Instead of putting into the guessedLetters array, try to see if the presses letter can be found in the randomWord.
If so, find the position of the letter and let it replace the appropriate _ space in the wordBlank array.
Something like:
function letterPressed(event) {
var letter = String.fromCharCode(event.keyCode);
if (randomWord.indexOf(letter) >= 0)
wordBlank[(randomWord.indexOf(letter)] = letter;
console.log(wordBlank);
}
Note that a letter may have multiple occurences in a word.

Related

Randomize words in a sentence / string with Javascript and list all the variations

i've searched a lot but havent found exactly what i am trying to do. But here goes:
I want to input a sentence / string in javascript and output all randomized variations of that sentence.
Example
input: 'my test sentence 123'
output: 'test my sentence 123', 'my sentence 123 test', '123 sentence my test', and so on, and stop when theres no variations left.
I've split the sentence into words in an array, but im a bit stuck on how to proceed to randomize the words and join them to new sentences in a list or new array.
code so far:
let str = "my test sentence 123";
let words = str.split(" ");
for (let i = 0; i < words.length - 1; i++) {
words[i] += " ";
}
A bit stuck on how to proceed. My thought process is: I have the words variable / array, but i need to randomize each word, output new strings but also check the existing ones so i don't duplicate any of them.
Thanks for all help i can get to learn more :)
Check this code
var phrase = "my test sentence 123";
var words = phrase.toLowerCase().match(/\w+/g);
var wordsCopy = phrase.toLowerCase().match(/\w+/g);
// First of all I loop each word
words.forEach(function(word, index){
// Random word going to contain my randomized word
var randomWord = word;
// Copy the entire phrase
var wordsMissing = wordsCopy.slice();
// Remove the current word
wordsMissing.splice(wordsCopy.indexOf(word), 1);
// Loop tru my missing words
for (var i = 0; i < wordsMissing.length; i++) {
// Set my random word with the rest of the words
randomWord += " " + wordsMissing.join(" ");
// get the first word and send to the final of my original phrase
var firstWord = wordsMissing.splice(0,1)[0];
wordsMissing.push(firstWord);
// Log my random word
console.log(randomWord);
// Reset random word to the initial word
randomWord = word;
}
});
As you are on Javascript, using .join(' ') will be easier to create a string from an array.
Then, there is a lot of solutions to achieve what you want to do, the easier way would be a foreach on foreach, where you simply test if the string you created already exists in the array.
It would be the easy way, but the more you put items, the more you will need power, so use this solution wisely.
Something like this can work :
var stringToSplit = 'I want to split this'
var stringSplitted = stringToSplit.split(' ')
var arrayOfNewStrings = []
stringSplitted.forEach(word => {
var arrayOfString = []
arrayOfString.push(word)
stringSplitted.forEach(otherWord => {
if(word !== otherWord)
arrayOfString.push(otherWord)
})
arrayOfNewStrings.push(arrayOfString)
});
console.log(arrayOfNewStrings)
You then need to add a layer of for/foreach to make it for every words (this will work only for the first one), and to test if the array already exists in ArrayOfNewStrings to prevent duplication.

Fuzzy searching using regex

I have an object with a key as some name to be searched and value its score, which looks like:
{
'a': 344,
'apple': 345354,
'orange': 320,
'mango': 39999,
.
.
.
}
The map has around half a million keys. I need to do a fuzzy search to create a test auto suggest like functionality (which supports typos) for some text like ornge and it should match orange and also return all words where matches occur. Also, matches could occur anywhere in the string, not just at the beginning. How could I do this using regex? I was trying the following:
(?=.*\ornge\b).*
but it does not work. How could I do this?
Using regex might not be the best solution. Could you suggest an alternative method?
Using regex isn't going to be all that simple. I agree with #apple apple that it would make sense to look for a library. I was intrigued about how long it would take to stub out a basic one by hand so I whipped this up, feel free to use/improve on it to optimize for working with that larger list that you have.
The basic gist is that you set a threshold for similarity in length between the input and expected output, and a minimum letter match score that you want to aim for.
For each word in your set, you run a comparison function between that word and the input. In the comparison function, you test each letter of the input against the word to see if it exists - if so, remove that letter from the word and move to the next one (to avoid inflated scores from multiple matches to the same letter: i.e. the string aaaaaa would score a 6 against apple if the a isn't removed after the first match)
If you wanted to enable multiple suggestions, you could replace the while(++i < listlen) loop with wordlist.filter, and return all words that fall above a certain score threshold.
const wordlist = ["apple", "orange", "mango", "fruit", "banana", "kiwi", "grapefruit"],
listlen = wordlist.length,
wordLengthDifferential = 1,
scoreDifferential = 3
function compare(str, word){
let score = 0
str = str.split('')
word = word.split('')
while(str.length){
let idx = word.indexOf(str.pop())
if(idx > -1){
++score
word.splice(idx, 1)
}
}
return score
}
function getSuggestion(str){
let highScore = 0, suggestion = null, i = -1
while(++i < listlen){
let word = wordlist[i]
if(Math.abs(word.length - str.length) <= wordLengthDifferential) {
let score = compare(str, word)
console.log(str, word, score)
if(score > highScore && score >= scoreDifferential){
suggestion = word
highScore = score
}
}
}
return suggestion || "no relevant matches"
}
document.querySelector('button').onclick = e => console.log(getSuggestion(document.querySelector('input').value))
document.addEventListener('keydown', e => {
if(e.keyCode == 13) console.log(getSuggestion(document.querySelector('input').value))
})
<input type="text" /><button>Go</button><em>(or press enter)</em>
For text input inputVal and your object obj.:
let regexString = '';
inputVal.split('').forEach(char => regexString += char + '.*');
const rgx = new RegExp(regexString, 'i');
const result = Object.keys(obj).filter(key => key.match(rgx));

Splitting sentence string into array of words, then array of words into arrays of characters within the array of words

I'm working through a problem on freecodecamp.com, and I want to see whether my code so far is doing what I think it is doing...
function titleCase(str) {
var wordArr = str.split(' '); // now the sentences is an array of words
for (var i = 0; i < wordArr.length; i++) { //looping through the words now...
charArr = wordArr[i].split(''); //charArr is a 2D array of characters within words?
return charArr[1][1];
}
}
titleCase("a little tea pot"); // this should give me 'i', right?
Again, this is just the beginning of the code. My goal is to capitalize the first letter of each word in the parameter of titleCase();. Perhaps I'm not even going about this right at all.
But... is charArr on line 4 a multidimensional array. Did that create [['a'],['l','i','t','t','l','e'],['t','e','a','p','o','t']]?
In addition to ABR answer (I can't comment yet) :
charArr is a one-dimensional array, if you want it to be a 2d array you need to push the result of wordArr[i].split(''); instead of assigning it.
charArr.push(wordArr[i].split(''));
And don't forget to initialize charArr as an empty array
Few issues :
1. Your return statement will stop this after one iteration.
2. If one of the words have fewer then 2 letters (like the first one in your example, which is 'a') - you will get an exception at charArr[1][1].
Other then that, it is mostly ok.
It would probably help you to download a tool like firebug and test your code live...
You can do the following:
function titleCase(str) {
var newString = "";
var wordArr = str.split(' ');
for (var i = 0; i < wordArr.length; i++) { //looping through the words now...
var firstLetter = wordArr[i].slice(0,1); // get the first letter
//capitalize the first letter and attach the rest of the word
newString += firstLetter.toUpperCase() + wordArr[i].substring(1) + " ";
}
return newString;
}
Also you need to remove the return statement in your for loop because the first time the for loop goes over the return statement, it will end the function and you will not be able to loop through all the words
Here you can learn more about string.slice() : http://www.w3schools.com/jsref/jsref_slice_string.asp

having an issue w/ .split in a JavaScript function that gets the max # of repeating chars per word in a string

I'm writing a JavaScript function that has to take in a string argument & determine the word or words with the maximum number or repeated (or most frequent) non sequential characters and return that word or words.
The way that I went about solving this problem was to first find the maximum number of times a character was repeated per word and record that number to use later in a function to test against every word in the string (or the array of strings as I later split it); if the word met the conditions, it's pushed into an array that I return.
My maxCount function seemed to work fine on its own but when I try to make it work together with my other function to get the words with max repeated chars returned, it's not working in JS Fiddle - it keeps telling me that "string.split is not a function" - I'll admit that the way I'm using it (string.split(string[i]).length) to analyze words in the string letter by letter is a bit unconventional - I hope there's some way to salvage some of my logic to make this work in the functions that can work together to get the results that I want.
Also, I don't know if I'm using Math.max correctly/in a "legal" way, I hope so. I've tried switching my variable name to "string" thinking that would make a difference but it did not even though my arguments are of the string variety and it's a string that's being represented.
Here's a link to my Fiddle:
https://jsfiddle.net/Tamara6666/rdwxqoh6/
Here's my code:
var maxCount = function (word) {
/// var maxRepeats = 0;
var numArray = [];
var string = word;
for (var i = 0, len = string.length; i < len; i++) {
//split the word('string') into letters at the index of i
numArray.push((string.split(string[i]).length) -1);
}
var max = Math.max(...numArray);
return max;
}
///console.log(maxCount("xxxxxxxxxxxxx"));
var LetterCount = function(string){
var repeatedChars = 0;
var wordArray=[];
var stringArray = string.split(" ");
for (var i = 0; i < stringArray.length; i++){
var eachWord = stringArray[i];
var maxRepeats = maxCount(stringArray);
if (repeatedChars < maxRepeats) {
repeatedChars = maxRepeats;
wordArray = [eachWord];
}else if (repeatedChars == maxRepeats) {
wordArray.push(eachWord);
}
}
return wordArray;
};
console.log(LetterCount("I attribute my success to cats"));
//should return ["attribute", "success"]
*** I've tried to map this first function onto the array formed when I split my string at the spaces but it is just returned me an empty array (I also might not have been using map correctly in this example); I also have tried using valueOf to extract the primitive value out of the array from the first function which also didn't work. I'm not really sure what to do at this point or what angle to take- I feel if I understood more what was going wrong I could more easily go about fixing it. Any help would be much appreciated. Thanks!
You are passing an array to maxCount at line 20, while it expects a string:
var maxRepeats = maxCount(stringArray);
You should use:
var maxRepeats = maxCount(eachWord);
If you are getting split is not a function error then first make sure that your string isn't null by printing it on console. If it isn't null then confirm that its a string not an array or some other thing.

One string multiple variables to check with indexOf

I have written a little JQuery / Javascript add on for our form, that takes a single full name input and breaks it into first and last name components. It opens a modal if there are three or more names in the input and asks which combo is correct.
My next step is finding and stripping any suffix that may have been entered such as Jr, Sr, III, etc. I am currently stripping off the last four characters and checking them with indexOf to see if they contain a suffix string (Jr, Sr, III, etc). But each line checks only one possible suffix and I am wondering is there is some js magic that will check multiple suffixs in one line. My current code is below:
var nameVal = $('#name').val();
var suffix = nameVal.slice(-4);
if (suffix.toLowerCase().indexOf(" jr") != -1) {
var nameSplit = nameVal.slice(0, -3).split(" ");
} elseif (suffix.toLowerCase().indexOf(" iii") != -1) {
var nameSplit = nameVal.slice(0, -4).split(" ");
} else {
var nameSplit = nameVal.split(" "); }
I can always do the good old || and keep adding extra (suffix.toLowerCase().indexOf(" jr") != -1) with a different indexOf value, but I am hoping to keep the code more compact if possible, my "little" script is already 3k.
Once I get this sorted the last step will be figuring out how to retain the last name value, so that further down the form when other names are entered and the script is called again it can check to see if the selected last name matches the new entry and bypass the modal pop up.
You can use a regular expression. Try something like this;
nameVal = nameVal.replace(/ (jr|sr|I?II)$/gi, "");
In more detail;
(jr|sr|I?II) = jr or sr or II or III
$ = at the end of line
/i = case insensitive
/g match globally
Probably best to use regexps for this, for example:
var names = [
"Joe Jr.",
"Mark Sr.",
"Loui III",
"Mark Lockering",
];
var suffixRes = [
/Jr\.$/, /Sr\.$/, 'III',
];
$(names).each(function(i, name) {
var str = name;
$(suffixRes).each(function(j, suffixRe) {
str = str.replace(suffixRe, '');
});
console.log(str);
});
Live example:
http://jsfiddle.net/am7QD/
In this case I usually make an array of values, (because I'm not good with regex)
var suffixArr = [' jr',' iii', ' ii'];
//then run a loop
for(var i = 0; i < suffixArr.length;i++){
if(suffixArr[i].toLowerCase().indexOf(suffixArr[i]) != -1){
nameSplit = nameVal.slice(0, - suffixArr[i].length).split(" ");
}
}

Categories