Javascript + HTML: Button Not Calling on Function Onclick - javascript

I have made a button:
<input type="button" value="a" onclick="searchLetter(this)"></input>
When clicked, it is supposed to call on a function which checks if the letter is in the word and if it is, add it to the spaces array in the corresponding spot:
function searchLetter(obj)
{
var letter = obj.value;
obj.disable;
for (i = 0; i <= word.length; i++){
if (word[i] == letter) {
wordSpaces[i] = letter;
document.getElementById('spaces').innerHTML = wordSpaces.join('');
break;
}
}
}
However, the button is not calling on it and I am not sure why.
Here is the JSFiddle (Hangman)

function pickWord() {
var word = dictionary[Math.floor(Math.random() * dictionary.length)];
var wordSpaces = [];
for (var i = word.length - 1; i >= 0; i--)
wordSpaces.push("_ ");
document.getElementById('spaces').innerHTML = wordSpaces.join('');
}
In your code, word and wordSpaces are a local variable to that function.
But in
function searchLetter(obj) {
var letter = obj.value;
for (var i = 0; i <= word.length; i++) {
you're trying to refer the word variable. That's why it's not entering the loop
So it must be like:
var word, wordSpaces;
function pickWord() {
word = dictionary[Math.floor(Math.random() * dictionary.length)];
wordSpaces = [];
for (var i = word.length - 1; i >= 0; i--)
wordSpaces.push("_ ");
document.getElementById('spaces').innerHTML = wordSpaces.join('');
}
function searchLetter(obj) {
var letter = obj.value;
for (var i = 0; i <= word.length; i++) {
if (word[i] == letter) {
wordSpaces[i] = letter;
document.getElementById('spaces').innerHTML = wordSpaces.join('');
break;
}
}
}

It's a scope issue. The searchLetter function is trying to access your word variable, but can't find it because it's in the other function and not within this function's scope.
One way to correct this is by declaring word in the global scope.

There is several errors in your code. You can use the console of your browser to see them (f12 opens it on all browsers, I think).
You have to declare the variables word and wordSpaces outside the pickWord function.
https://jsfiddle.net/gael/3vdwLasc/3/
You should also verify that the word has been initialized when you click on a letter.

Related

Can't create an opportune return for my function

I have to create a function that checks if a word is palindrome or not. My reasoning is to break down the word letter by letter, normal and reverse, and then compare the two results to determine if a word is a palindrome or not. With an if - else I give the user an alert that tells perfectly the result. Now, I've learned that most of the functions must have a return with a variable that contains that desired result.
In this case I really can't have this, I think it can work perfectly this way. I tried with
var palindromeResult = (leftToRightWord == rightToLeftWord) ? 'true':'false';
console.log(palindromeResult);
return palindromeResult;
but it works only for the developer if he reads the console.log in the console, but it's a bad solution for me... Have you got any better idea than this? Below my full function code
function isPalindrome(wordToCheck) {
for(var i = 0; i < wordToCheck.length; i++) {
var leftToRightWord = wordToCheck[i];
console.log('Left ' + leftToRightWord);
}
for(var j = wordToCheck.length - 1; j >= 0; j--) {
var rightToLeftWord = wordToCheck[j];
console.log('Right ' + rightToLeftWord);
}
if ( leftToRightWord === rightToLeftWord) {
alert('La parola è palindroma');
} else {
alert('La parola non è palindroma');
}
Edit: At the end I changed a lot my code for a better legibility.
//Data
var userWord;
//I ask a word to the user
do {
userWord = prompt("Dimmi una parola");
} while (userWord.length === 0)
//Here the result of the function is saved and it can be reused
var functionResult = isPalindrome(userWord);
console.log (functionResult);
//Function to know if the word inserted is a palindrome or not
//the cycle with rightToLeft reverse the word so it can be compared to the normal word
//A pop-up will give the solution so it can be seen clearly on your screen
//The function result will ben saved outside the function in var functionResult so it can be seen with a console.log or reused for whatever use
function isPalindrome(wordToCheck) {
var rightToLeftWord = '';
for(var j = wordToCheck.length - 1; j >= 0; j--) {
rightToLeftWord = rightToLeftWord + wordToCheck[j];
}
console.log(rightToLeftWord);
var palindromeResult = wordToCheck == rightToLeftWord;
alert(palindromeResult);
return palindromeResult;
}
Now the cycle with for doesn't have problems anymore as you've pointed out to me and it correctly recognize if a word is a palindrome or not.
See the snippet. The function returns the answer and then you can alert it, assign it to a variable, echo it on the page and so on. I'm not pretty sure about your algorithm since it is telling me that 'abracadabra' is palindrome but it is not. RTL the sequence of the letters is wrong!
function isPalindrome(wordToCheck) {
for (var i = 0; i < wordToCheck.length; i++) {
var leftToRightWord = wordToCheck[i];
console.log('Left ' + leftToRightWord);
}
for (var j = wordToCheck.length - 1; j >= 0; j--) {
var rightToLeftWord = wordToCheck[j];
console.log('Right ' + rightToLeftWord);
}
if (leftToRightWord === rightToLeftWord) {
return 'La parola è palindroma';
} else {
return 'La parola non è palindroma';
}
}
alert(isPalindrome('abracadabra'));

Return the first word with the greatest number of repeated letters

This is a question from coderbyte’s easy set. Many people asked about it already, but I’m really curious about what’s wrong with my particular solution (I know it’s a pretty dumb and inefficient one..)
Original question:
Have the function LetterCountI(str) take the str parameter being passed and return the first word with the greatest number of repeated letters. For example: "Today, is the greatest day ever!" should return greatest because it has 2 e's (and 2 t's) and it comes before ever which also has 2 e's. If there are no words with repeating letters return -1. Words will be separated by spaces.
My solution works most of the time. But if it seems the last word of the input isn’t valued by my code. For example, for “a bb ccc”, “bb” will be returned instead of “ccc”. But the funny thing here is if the string only contains one word, the result is correct. For example, “ccc” returns “ccc”.
Please tell me where I was wrong. Thank you in advance!
function LetterCountI(str) {
str.toLowerCase();
var arr = str.split(" ");
var count = 0;
var word = "-1";
for (var i = 0; i < arr.length; i++) {
for (var a = 0; a < arr[i].length; a++) {
var countNew = 0;
for (var b = a + 1; b < arr[i].length; b++) {
if(arr[i][a] === arr[i][b])
countNew += 1;
}
if (countNew > count) {
count = countNew;
word = arr[i];
}
}
return word;
}
}
Please find below the workable version of your code:
function LetterCountI(str) {
str = str.toLowerCase();
var arr = str.split(" ");
var count = 0;
var word = "-1";
for (var i = 0; i < arr.length; i++) {
for (var a = 0; a < arr[i].length; a++) {
var countNew = 0;
for (var b = a + 1; b < arr[i].length; b++) {
if (arr[i][a] === arr[i][b])
countNew += 1;
}
if (countNew > count) {
count = countNew;
word = arr[i];
}
}
}
return word;
}
Here is the Java code soln for your problem.
You have returned your answer incorrectly. You should have returned word/Answer/res out of "for loops".
Check my chode here.
public static String StringChallenge( String str) {
String[] arr = str.split(" ");
int count = 0; String res = "-1";
for (int i = 0; i < arr.length ; i++) {
for (int j = 0; j < arr[i].length() ; j++) {
int counter = 0;
for (int k = j + 1; k < arr[i].length() ; k++) {
if(arr[i].charAt(j) === arr[i].charAt(k) )
counter ++;
}
if (counter > count) {
count = counter; res = arr[i];
}
}
return res;
}
}
I think the problem is that you're placing the return statement inside your outermost loop. It should be inside your inner loop.
So you have to place the return statement within the inner loop.
Correct use of return
if (countNew > count) {
count = countNew;
word = arr[i];
}
return word;
}
}
}
You need to move the return word; statement outside of the loop to fix your version.
I also put together another take on the algorithm that relies on a few built in javascript methods like Array.map and Math.max, just for reference. I ran a few tests and it seems to be a few milliseconds faster, but not by much.
function LetterCountI(str) {
var maxCount = 0;
var word = '-1';
//split string into words based on spaces and count repeated characters
str.toLowerCase().split(" ").forEach(function(currentWord){
var hash = {};
//split word into characters and increment a hash map for repeated values
currentWord.split('').forEach(function(letter){
if (hash.hasOwnProperty(letter)) {
hash[letter]++;
} else {
hash[letter] = 1;
}
});
//covert the hash map to an array of character counts
var characterCounts = Object.keys(hash).map(function(key){ return hash[key]; });
//find the maximum value in the squashed array
var currentMaxRepeatedCount = Math.max.apply(null, characterCounts);
//if the current word has a higher repeat count than previous max, replace it
if (currentMaxRepeatedCount > maxCount) {
maxCount = currentMaxRepeatedCount;
word = currentWord;
}
});
return word;
}
Yet another solution in a more functional programming style:
JavaScript
function LetterCountI(str) {
return ((str = str.split(' ').map(function(word) {
var letters = word.split('').reduce(function(map, letter) {
map[letter] = map.hasOwnProperty(letter) ? map[letter] + 1 : 1;
return map;
}, {}); // map of letters to number of occurrences in the word
return {
word: word,
count: Object.keys(letters).filter(function(letter) {
return letters[letter] > 1;
}).length // number of repeated letters
};
}).sort(function(a, b) { // Sort words by number of repeated letters
return b.count - a.count;
}).shift()) && str.count && str.word) || -1; // return first word with maximum repeated letters or -1
}
console.log(LetterCountI('Today, is the greatest day ever!')); // => greatest
Plunker
http://plnkr.co/edit/BRywasUkQ3KYdhRpBfU2?p=preview
I recommend use regular expression: /a+/g to find a list of letter with a key word a.
My example :
var str = aa yyyyy bb cccc cc dd bbb;
Fist, find a list of different word :
>>> ["a", "y", "b", "c", "d"]
Use regular expression for each word in list of different word :
var word = lstDiffWord[1];
var
wordcount = str.match(new RegExp(word+'+','g'));
console.log(wordcount);
>>>>["yyyyy"]
Here is full example: http://jsfiddle.net/sxro0sLq/4/

Javascript Learnstreet Email Interpreter Alternative Solution

So I was doing this assignment on Learnstreet and for those of you who want to read a little on the question here's the link:
http://www.learnstreet.com/cg/simple/project/email_interpret#check
Long story short - you're given a email string like "local#domain.com" and you're expected to return a 2 member array that would look like ["local","domain"]. So I wrote this and am wondering how this is not correct.
function extractLocalDomain(str)
{
var text = str.trim(); //eliminates leading and trailing spaces
for(var i = 0; i < text.length; i++) {
if(text[i] == "#") {
var local = text.slice(0, i-1);
var domain = text.slice(i+1)
return [local,domain];
}
i++
}
}
You are incrementing i twice:
function extractLocalDomain(str) {
var text = str.trim();
for (var i = 0; i < text.length; i++) { // <- increment here
if (text[i] == "#") {
var local = text.slice(0, i - 1);
var domain = text.slice(i + 1)
return [local, domain];
}
i++ // <- and here agin, remove this
}
}
Instead of using a loop, you can also just use .indexOf.

How can I shortened this?

I am trying to self teach myself programming and started with javascript. To learn more I have been completing challenges to practice and one challenge was to write a script that would determine the first case of the word in a string with the most repeated letters. I was able to complete it with this code I made:
string = "Hey i believe";
string = string.split(" ");
stringarray = [];
longestlength = 0;
for (i = 0; i < string.length; i++) {
stringarray.push(0);
}
for (i = 0; i < string.length; i++) {
if (string[i].length > longestlength) {
longestlength = string[i].length;
longestword = string[i];
}
}
for (x = 0; x < string.length; x++) {
y = 0;
z = 0;
while (z < string[x].length) {
if (string[x].substr(z,1) == string[x].substr(y,1) && z !== y) {
stringarray[x] += 1;
y = string[x].length -1;
}
y++;
if (y == string[x].length) {
z++;
y = z;
}
}
}
if (Math.max.apply(null,stringarray) === 0) {
mostrptltword = -1;
}
else {
mostrptltword = string[stringarray.indexOf(Math.max.apply(null,stringarray))];
}
console.log(mostrptltword);
But to get all the points possible for the challenge it must be completed in less than 10 minutes this took me 25 mins. So my question is am I over complicating things; causing me to write a much longer script than needed? I have read a little bit about things like Regular Expressions and how they can really shortened script lengths and the time it takes to write them would that or maybe another technique of been more useful than all the loops I had to make?
var words = "Heyyyyy I believe".split(' '); // split the words into an array
var values = [], // total of times that a letter appears
k = 0, // 'global' counter. I'm using this to iterate over the values array
heigher = 0, // holds de heigher occurrence of a letter
letter = ""; // the letter that most appears in that word
word = ""; // the word
// iterate over all the words
for(var i = 0; i < words.length; i++) {
// iterate over each letter in each word
for(var j = 0; j < words[i].length; j++) {
// holds the occurrence time
// RegEx: get the word in the position 'i' and check how many times the letter appears on the position [j] appears
values[k] = words[i].match(new RegExp(words[i][j],'g')).length;
// check if the next letter appears more times than the previous one
if(values[k] > heigher) {
// hold the values of interest
heigher = values[k];
letter = words[i][j];
word = words[i];
}
k++;
}
}
console.log("word: " + word + " letter: " + letter + " total: " + heigher);
jsfiddle: http://jsfiddle.net/felipemiosso/FyCHG/
The is commented. Hope it helps :)

For loop in Javascript runs only once

Here is my code. I do not quite understand why the for loop runs only once, both inner and outer. nodeList.length and innerNodeList.length show appropriate values when I generate alert messages. I see that both i and j do not increment beyond 0. Kindly point out anything wrong with the code.
function getCategoryElements() {
var newCategoryDiv = document.getElementById("category");
var nodeList = newCategoryDiv.childNodes;
for (var i = 0; i < nodeList.length; ++i) {
var innerNodeList = nodeList[i].childNodes;
alert("innerNodeList Length" + innerNodeList.length.toString());
for (var j = 0; j < innerNodeList.length; ++j) {
if (innerNodeList[j].nodeName == "SELECT") {
alert("inside select Node value " + innerNodeList[j].nodeValue.toString());
document.getElementById("newCategories").value =
document.getElementById("newCategories").value + '<%=delimiter%>' + innerNodeList[j].nodeValue;
} else if (innerNodeList[j].nodeName == "TEXTAREA") {
document.getElementById("newCategoriesData").value =
document.getElementById("newCategoriesData").value + '<%=delimiter%>' + innerNodeList[j].nodeValue;
}
}
}
}
var newCategoryDiv, nodeList, innerNodeList, innerNode, i, j;
newCategoryDiv = document.getElementById("category");
nodeList = newCategoryDiv.childNodes;
for (i = 0; i < nodeList.length; ++i) {
innerNodeList = nodeList[i].childNodes;
alert("innerNodeList Length" + innerNodeList.length.toString());
for (j = 0; j < innerNodeList.length; ++j) {
innerNode = innerNodeList[j];
if (innerNode.nodeName === "SELECT") {
alert("inside select Node value " + innerNode.nodeValue.toString());
document.getElementById("newCategories").value += '<%=delimiter%>' + innerNode.nodeValue;
} else if (innerNode.nodeName === "TEXTAREA") {
document.getElementById("newCategoriesData").value += '<%=delimiter%>' + innerNode.nodeValue;
}
// Will this work?
alert('Does this alert appear');
}
}
I took the liberty to refactor your code and clean it up a little bit. In case you're not aware, all variables have function scope in Javascript, so no matter where you declare them within a single function, Javascript treats them as if the variable declaration is the first statement.
It appears that your code is syntactically correct, and so I think that the most logical place to look for a problem is that there could be an error occurring after the last alert function call.
In order to check this, try adding another alert function call to the end of the inner loop. If it doesn't run, you'll know this is the case.

Categories

Resources