What is wrong with my for loop? - javascript

I'm a newbie on Javascript and I'm trying to do some exercises. I have found other ways on here that are more efficient at solving this, but anyway, here's how I tried doing it:
var char = prompt("Give me a letter");
char = char.toLowerCase();
function isVowel(char){
var vowels = new Array('a','e','i','o','u');
for(i = 0; i < vowels.length; i++){
if(vowels[i] == char){
return "This letter is a vowel.";
}else{
return "This letter is not a vowel.";
}
}
}
alert(isVowel(char));
Now, I understand this isn't the best way to do this, but I'd like to understand what's wrong with my for loop, since "a" is the only letter it recognizes as being a vowel.
Can someone point me out the reason why it isn't running trough the whole array?
Thanks in advance

You should not return until you have a definite "yes" or "no" answer.
Try something like this instead:
var char = prompt("Give me a letter");
char = char.toLowerCase();
function isVowel(char){
var vowels = new Array('a','e','i','o','u');
for(i = 0; i < vowels.length; i++){
if(vowels[i] == char){
return "This letter is a vowel.";
}
}
return "This letter is not a vowel.";
}
alert(isVowel(char));

var char = prompt("Give me a letter");
char = char.toLowerCase();
function isVowel(char){
var vowels = new Array('a','e','i','o','u');
var isv = false;
for(i = 0; i < vowels.length; i++){
if(vowels[i] == char){
isv = true;
}
}
if( isv == true)
return "This letter is a vowel.";
else
return "This letter is not a vowel.";
}
}
alert(isVowel(char));

The reason it isn't running through the whole array is because you return a value. That stops the function after the first iteration.
Here's a simpler solution to identify vowels without having to loop through an array:
function isVowel(char) {
if (vowels.indexOf(char) >= 0) {
return "The character \""+char+"\" is a vowel.";
} else {
return "The character \""+char+"\" is NOT a vowel.";
}
}
var vowels = new Array('a','A','e','E','i','I','o','O','u','U');
alert(isVowel('e'));
alert(isVowel('f'));
The indexOf functionality is based on the answer here.
Here's a working example (jsFiddle).

Related

To lower case using if else/ for

I am the very begginer (only if/else, for, while, slice etc) and i ve got a problem: so i wrote Hangman game. I need to put in there code saying ‘’let’s player upper case guess letter transform to lowercase one every time he puts uppercase letter”
Did i choose the right place for this new code in existing code?
Were my thoughts about appropriate code more or less right?
If not: what s wrong then?
var words = ["fish", "monkey", "pioni", "agreable"];
var randomWord = words[Math.floor(Math.random() * words.length)];
var answerArray = [];
for (var i = 0; i < randomWord.length; i++) {
answerArray[i] = "_";
}
var ramainingLetters = randomWord.length;
//Game circle
while (ramainingLetters > 0) {
alert(answerArray.join(" "));
var guess = prompt("Guess a letter or press cancel to exit game");
if (guess === null) {
break;
} else if (guess.length !== 1) {
alert("Enter only one letter");
} else if (guess == guess.toUpperCase()) {
guess = guess.toLowerCase();
} else {
//renew game cycle
for (var j = 0; j < randomWord.length; j++) {
if (randomWord[j] === guess) {
answerArray[j] = guess;
ramainingLetters--;
}
}
}
// stop game
}
alert(answerArray.join(" "));
alert(" Cool! this word was " + randomWord);
You could easily solve your problem by converting the chosen word to uppercase and everytime the user puts in a letter, make that uppercase too.
var randomWord = words[Math.floor(Math.random() * words.length)].toUpperCase();
And convert your quess always to uppercase
guess = guess.toUpperCase();
This way everything is consistent.
If they type in a letter in lowercase its getting converted to uppercase and compared with the word also in uppercase.

checking the same condition for all elements in array javascript

I'm trying to code a basic hangman game. When the user guesses correctly the word then the word is uploaded to an "answer" array and displayed to the user , when the guessed word is wrong then a warning should say "try again" and the input value cleared.
The thing is even when one word is actually guessed correctly there's still all the other words that were not so I end up getting the same warning "try again"
So I think I need to loop the original word and check to see if none of the elements are equal to the letter guess and for that I'm using every() but I can't make it work and "try again" always shows...
Help please
function generate(){
pickedWord = words[Math.floor(Math.random() * words.length)];
console.log(pickedWord)
for(let i = 0; i<pickedWord.length; i++){
word[i] = "_";
}
wordGuess.textContent = word.join(" ");
}
function getInput(e){
e.preventDefault();
let guess = input.value.toLowerCase();
if(guess.length > 1){
alert("type just one letter")
input.value = ""
}
else{
for(let i=0; i < pickedWord.length; i++){
if(guess === pickedWord[i]){
word[i] = guess;
wordGuess.textContent = word.join(" ");
input.value="";
}
else {
const letter = [pickedWord[i]]
console.log(letter)
const itemGuessed = letter.every(el => el !== guess)
if(itemGuessed){
alerta.textContent = "try again"
input.value="";
}
}
}
}
}
```
You actually didn't specify what does the words array look like, so I'm gonna assume tht it's an array of strings. Something like
const words = ['applejuice', 'bananashake', 'peanutbutter'];
So first of all, I actually don't understand what is the purpose of const letter = [pickedWord[i]]. Say the picked word was 'apple', and i was 0, then letter will be equal to ['a'], which makes the line const itemGuessed = letter.every(el => el !== guess) completely meaningless.
I also think it's better to check if guess is included in the pickedWord outside of the loop, using either pickedWord.every(el => el !== guess) or pickedWord.includes(guess) (though I prefer the latter!).
Anyway, I had a little rewrite on your code:
let pickedWord;
const words = ['applejuice', 'bananashake', 'peanutbutter'];
let word = [];
function generate() {
pickedWord = words[Math.floor(Math.random() * words.length)];
word = Array(pickedWord.length).fill('_');
console.log(pickedWord, word.join(''));
}
let guessedLetters = [];
function getInput(input){
// e.preventDefault();
const guess = input.toLowerCase().replace(/\s/g, '');
if(guess.length !== 1){
alert("type one letter");
}else{
if (pickedWord.includes(guess) === -1) {
alert("letter not in word");
}else if(guessedLetters.includes(guess)) {
alert("that letter is already guessed");
}else{
guessedLetters.push(guess)
for (let i = 0; i < pickedWord.length; i++) {
if(guess === pickedWord[i]){
word[i] = guess;
}
}
}
}
}
generate();
//cases where 1: same letter guessed twice
// 2: more than 1 letters guessed at once
// 3: capital letters guessed
// 4: empty string / space guessed
for (let input of ['', ' ', 'a', 'a', 'B', 'c', 'Cc', 'd', 'E', 'f', 'g', 'h']){
getInput(input);
console.log(word.join(''));
}
Note that I removed input.value=""; line for the demonstration purposes.
Please feel free to ask anything if you had a problem with my code. cheers!

How can I find if ALL of string2 letters are also contained within string1 somewhere?

I am trying to compare two strings to see if ALL of one of the string's input is also within another string, regardless of order.
So far I have the following code...
What am I doing wrong?
var str1= "rkqodlw"
var str2= "world"
StringScrambler(str1, str2);
function StringScrambler(str1, str2) {
var string1= str1.split("").sort();
console.log(string1);
var string2 = str2.split("").sort();
console.log(string2);
matches = [];
for (i=0; i< string1.length; i++) {
for (j=0; j<string2.length; i++) {
while (j === i) {
matches.push(j);
console.log(matches);
var matchSort = matches.sort();
console.log(matchSort);
if (matchSort === string2) {
return true;
}else {
return false;
}
}
}
}
}
All the answers this far work fine but they will not work for words with double letters in the second string but not in the first (for eg. 'worlld' - notice the double L). The trick is to affect the first word such that it removes the found character(s) so that the same letter is not checked again. Something like this would do the trick:
// Check if the second string's characters are
// found in the first string
function StringScrambler(str1, str2) {
var arr1 = str1.split(''),
arr2 = str2.split(''),
isATrueSubset = true,
indexOfChar;
arr2.forEach(function(char) {
indexOfChar = arr1.indexOf(char);
if (indexOfChar > -1) {
// Remove the character that was found
// to avoid matching against it again
arr1.splice(indexOfChar, 1);
} else {
isATrueSubset = false;
// No need to continue
return;
}
});
console.log(isATrueSubset);
return isATrueSubset;
}
StringScrambler('rkqodlw ', 'world '); // outputs true
StringScrambler('rkqodlw ', 'worlld '); // outputs false
var one = "dlrow";
var two = "world";
var allCharsFound = true;
one.split("").map(function(char) {
if (two.indexOf(char) < 0) {
allCharsFound = false;
}
});
console.log(allCharsFound);
var str1= "rkqodlw";
var str2= "world";
function test($str1, $str2) {
var string2 = str2.split("");
for(var i=0; i<string2.length; i++) {
if (str1.indexOf(string2[i]) == -1) {
return false;
}
}
return true;
}
You can use the following code to do this task:
alert (AllFirstInSecond("world", "rkqodlw"));
alert (AllFirstInSecond("worldz", "rkqodlw"));
function AllFirstInSecond(str1, str2) {
var pos = str1.length - 1;
while (pos >= 0) {
if (str2.indexOf(str1.substr(pos--,1)) == -1) {
return false;
}
}
return true;
}
It simply checks every single character in the first string to see if it's in the second. If not, it returns false.
Only once all have been found does it return true.
There are possibilities for optimisation (every character is checked even if it's a duplicate that's already been checked) but, unless your strings are particularly large, there's probably not much absolute gain to be had.
If str2 is always a subset of str1, then this answer can be used
Compute intersection of two arrays in JavaScript
var arr1 = "rkqodlw".split("");
var arr2 = "world".split("");
var commonValues = arr2.filter(function(value) {
return arr1.indexOf(value) > -1;
});
alert(commonValues.join(""))
This will compare each words of the second string in the first one and if its present it will be added in the mathes array.
var str1= "rkqodlw";
var str2= "world2";
StringScrambler(str1, str2);
function StringScrambler(str1, str2) {
var string2 = str2.split("").sort();
console.log(string2);
matches = [];
for (j=0; j<string2.length; j++) {
if(str1.indexOf(string2[j]) > -1){
matches.push(string2[j]);
console.log(string2[j]);
}
}
console.log(matches);
}
try this:
var str1= "rkqodlw"
var str2= "world"
StringScrambler(str1, str2);
function StringScrambler(str1, str2) {
var string1 = str1.split("").sort();
var string2 = str2.split("").sort();
matches = [];
for (i = 0; i < string1.length; i++) {
if (string2.indexOf(string1[i]) > -1) matches.push(string1[i]);
}
return matches
}

how to find the most repeat word in string?

can you please tell me how to find the most repeat word in string ?
Example
If input is this
"how do you do"
Output is "do"
var str="how do you do"
function findMostReaptedWord(str){
var res = str.split(" ");
alert(res.length);
var count;
var compareString;
for(var i=0;i<res.length ;i++){
count=0;
compareString=res[i]
for (j=0;i<res.lenth ;j++){
if(compareString==res[j]){
count++
}
}
}
}
alert(findMostReaptedWord(str))
fiddle
http://jsfiddle.net/omjg9v0q/
I gave the idea in a comment. Here it is in code :
function findMostReaptedWord(str){
var counts = {}, mr, mc;
str.match(/\w+/g).forEach(function(w){ counts[w]=(counts[w]||0)+1 });
for (var w in counts) {
if (!(counts[w]<mc)) {
mc = counts[w];
mr = w;
}
}
return mr;
}
A few details :
I use str.match(/\w+/g) for a better decomposition in words. Yours would take anything not a space as a word or part of a word.
counts is a map giving the number of occurrences of each words (i.e. counts["do"] is 2)
using a map avoids doing two levels of loop, which is very slow
Here is my approach
First, separate the words from the string using Regular Expression.
Declare an object as a Map which will help you to find the occurrences of each word. (You can use Map Data Structure!)
Find the most repeated word from that object.
let str = 'How do you do?';
console.log(findMostRepeatedWord(str)); // Result: "do"
function findMostRepeatedWord(str) {
let words = str.match(/\w+/g);
console.log(words); // [ 'How', 'do', 'you', 'do' ]
let occurances = {};
for (let word of words) {
if (occurances[word]) {
occurances[word]++;
} else {
occurances[word] = 1;
}
}
console.log(occurances); // { How: 1, do: 2, you: 1 }
let max = 0;
let mostRepeatedWord = '';
for (let word of words) {
if (occurances[word] > max) {
max = occurances[word];
mostRepeatedWord = word;
}
}
return mostRepeatedWord;
}
Here I give you an approach,
Sort the words first. That way "how do you do" becomes "do do how you".
Iterate the string to count the words that repeat, keep the maximum number of times repeating word in memory while iterating.
-
Mebin
This function may help you
function maxWord (str)
{
var max = 0;
var maxword = '';
var words = str.split(' ');
for(i=0;i<words.length;i++)
{
var count = 0;
var word = '';
for(j=0;j<words.length;j++)
{
if(j !== i && words[i] === words[j])
{
count++;
word = words[i];
}
}
if(count>maxword)
{
max = count;
maxword = word;
}
}
return maxword;
}
maxWord('how do you do'); // returns do

Javascript Last Letter getting cut off

Alright, so basically this code passes in a sentence into the function and the function needs to figure out which word is longest to return. Everything works great except that the very last letter keeps getting cut off. So what would be a good solution to this problem?
function LongestWord(sen) {
sen = sen.toLowerCase();
var build = "";
var arr = [];
var longest = 0;
for(var i = 0; i < sen.length;i++){
var cur = sen.charCodeAt(i);
console.log(sen.charCodeAt(i))
if(i == sen.length - 1){
arr.push(build);
}
if(sen.charAt(i) === " "){
arr.push(build);
build = "";
}
if(cur >= 97 && cur <= 122){
build += String.fromCharCode(cur);
}
}
console.log(arr);
for(var e = 0; e < arr.length - 1;e++){
if(arr[e].length > arr[e + 1].length){
longest = arr[e];
}
else{
longest = arr[e + 1];
}
}
return longest;
}
// keep this function call here
// to see how to enter arguments in JavaScript scroll down
console.log(LongestWord("Johnny ErsoL"));
It returns "Johnny", which is correct, but this is what the Array looks like at the end.
[ 'johnny', 'erso' ]
Here's my suggestion ?
function LongestWord(sen) {
return sen.split(/\b/).filter(function(item) {
return item.trim().length;
}).sort(function(a,b) {
return b.length - a.length;
});
}
split the sentence on word boundary, then trim off empty spaces, finally sort by length of each word and return the sorted array.
Try replacing
for(var i = 0; i < sen.length;i++){
var cur = sen.charCodeAt(i);
console.log(sen.charCodeAt(i))
if(i == sen.length - 1){
arr.push(build);
}
if(sen.charAt(i) === " "){
arr.push(build);
build = "";
}
if(cur >= 97 && cur <= 122){
build += String.fromCharCode(cur);
}
}
with
arr=sen.split();
You have a for loop with e <arr.length -1. I don't think you need the -1.
I know you already found your answer, however I just wanted to show you an alternative to what you are doing.
To simplify your code and also make it more understandable, but also flexible, it's usually a good idea to make sure that every function does only one thing, or has a single responsability.
In your code, your LongestWord function has the responsability to identify what is a word and to find out which one is the longest.
What you could have done is create a function that knows how to tokenize a sentence into words:
function forEachWordsIn(str, callback) {
var rx = /\b(\w+?)\b/g,
match;
while (match = rx.exec(str)) callback(match[0]);
}
Then use that words iterator function from the longestWord function, which makes this algorithm extremely trivial now:
function longestWord(sen) {
var longestWord = '';
forEachWordsIn(sen, function (word) {
if (word.length > longestWord.length) longestWord = word;
});
return longestWord;
}
Note: I renamed LongestWord to longestWord because making functions start with captital letters is a well known standard to identify constructor functions.

Categories