I am trying to create an text encrypter, but when i entered this code, nothing happens. What is wrong with my code?
function Encrypt(txt) {
var chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 'y', 'z'}
for (i = 0; i < txt.length; i++) {
var chr = txt.charAt(i);
var pos = chars.indexOf(chr);
if (pos == chars.length) {
pos = 0;
}
else {
pos = pos++
}
txt.charAt(i) = chars[pos];
}
alert(txt);
}
You need
array [] instead of object {},
some declared variables
an empty result string newText, a string is read only with the character access
a valid check if the letter is not in the array
increment pos without assignment.
append the result string with the encoded character
function Encrypt(txt) {
var chars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
i, newText = '', chr, pos;
for (i = 0; i < txt.length; i++) {
chr = txt[i];
pos = chars.indexOf(chr);
if (!~pos) {
pos = 0;
} else {
pos++;
}
newText += chars[pos];
}
document.write(newText);
}
Encrypt('test');
Because this is not an array, but object... and object has to have "index" : "value" structure.
Change this:
var chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 'y', 'z'}
to this:
var chars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 'y', 'z']
Not considering the errors well described in the other answers, my proposal to encrypt a string is:
function Encrypt(txt) {
var chars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 'y', 'z'];
var txtResult = txt.split('').map(function(val) {
var pos = chars.indexOf(val);
return chars[(pos == chars.length) ? 0 : (pos + 1)];
}).join('');
document.write(txtResult);
}
Encrypt('gaemaf');
Related
Javascript beginner here. This function is supposed to show the position of any given letter in the English alphabet. It seems to run fine, but along with the result, I get an undefined error. Where is this coming from?
var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
function position(letter){
letter = letter.toLowerCase();
for (var i = 0; i < alphabet.length; i++) {
if (alphabet[i] === letter){
console.log('Position in the alphabet is: ' + i);
break;
}
}
};
console.log(position("Z"));
Change:
console.log(position("Z"));
to:
position("Z");
Function position does not return anything--that is why you are getting undefined.
You aren't return any values from position(...) function. To fix the undefined error, you might want to return null if no result is found, like the example:
var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
function position(letter){
letter = letter.toLowerCase();
for (var i = 0; i < alphabet.length; i++) {
if (alphabet[i] === letter){
return 'Position in the alphabet is: ' + i;
}
}
return null;
};
console.log(position("Z"));
The undefined you are seeing in the console is not an error at all. Instead, it is the result of the console.log() statement in last line of code, as #Russ mentioned. It is logging what it received after executing position("Z") - which is actually nothing or undefined.
If you wish to be able to use console.log() for the output of your function, you could have it return a string. This would also eliminate the need for a break; statement in your for loop. You might include a "not found" type of default statement as well to protect against an actual error. (#Dorado's null default is a good alternative.) Here's what my suggestion might look like for your code:
var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
function position(letter){
letter = letter.toLowerCase();
for (var i = 0; i < alphabet.length; i++) {
if (alphabet[i] === letter){
return('Position in the alphabet is: ' + i);
}
}
return 'Character not found in the alphabet!';
};
console.log(position("Z"));
This would give you the single console output you desire, remove the undefined from your console, and allow you to use this function in other code.
your function could be simply this:
var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
function position=(letter)=> {
console.log(`Position in the alphabet is: ${alphabet.findIndex(el=>el===letter.toLowerCase())}`)
}
position("Z");
I am trying to make a boggle game in Js and I want to add some features to make life more simpler. And not having to duplicate my code a thousand times. Basically I have a function called addLetter() which simply pushes the letter clicked on to an array. It only works for one letter right now and I dont want to hardcode it. So how can I pull the value from the clicked div? I dont want to make 16 functions to push one letter from a single div.
Source code:
var letters = [];
const random = Math.floor(Math.random() * 6);
var dice1 = ['R', 'I', 'F', 'O', 'B', 'X'];
var dice2 = ['I', 'F', 'E', 'H', 'E', 'Y'];
var dice3 = ['D', 'E', 'N', 'O', 'W', 'S'];
var dice4 = ['U', 'T', 'O', 'K', 'N', 'D'];
var dice5 = ['H', 'M', 'S', 'R', 'A', 'O'];
var dice6 = ['L', 'U', 'P', 'E', 'T', 'S'];
var dice7 = ['A', 'C', 'I', 'T', 'O', 'A'];
var dice8 = ['Y', 'L', 'G', 'K', 'U', 'E'];
var dice9 = ['Q', 'B', 'M', 'J', 'O', 'A'];
var dice10 = ['E', 'H', 'I', 'S', 'P', 'N'];
var dice11 = ['V', 'E', 'T', 'I', 'G', 'N'];
var dice12 = ['B', 'A', 'L', 'I', 'Y', 'T'];
var dice13 = ['E', 'Z', 'A', 'V', 'N', 'D'];
var dice14 = ['R', 'A', 'L', 'E', 'S', 'C'];
var dice15 = ['U', 'W', 'I', 'L', 'R', 'G'];
var dice16 = ['U', 'W', 'I', 'L', 'R', 'G'];
var dice1rnd = (dice1[random]);
var dice2rnd = (dice2[random]);
var dice3rnd = (dice3[random]);
var dice4rnd = (dice4[random]);
var dice5rnd = (dice5[random]);
var dice6rnd = (dice6[random]);
var dice7rnd = (dice7[random]);
var dice8rnd = (dice8[random]);
var dice9rnd = (dice9[random]);
var dice10rnd = (dice10[random]);
var dice11rnd = (dice11[random]);
var dice12rnd = (dice12[random]);
var dice13rnd = (dice13[random]);
var dice14rnd = (dice14[random]);
var dice15rnd = (dice15[random]);
var dice16rnd = (dice16[random]);
console.log(dice1[random]);
console.log(dice2[random]);
console.log(dice3[random]);
console.log(dice4[random]);
console.log(dice5[random]);
console.log(dice6[random]);
console.log(dice7[random]);
console.log(dice8[random]);
console.log(dice9[random]);
console.log(dice10[random]);
console.log(dice11[random]);
console.log(dice12[random]);
console.log(dice13[random]);
console.log(dice14[random]);
console.log(dice15[random]);
console.log(dice16[random]);
console.log(letters);
document.getElementById('dice1rnd').innerHTML = dice1rnd;
document.getElementById('dice1rnd').addEventListener("click", addLetter, false);
document.getElementById('dice2rnd').innerHTML = dice2rnd;
document.getElementById('dice3rnd').innerHTML = dice3rnd;
document.getElementById('dice4rnd').innerHTML = dice4rnd;
document.getElementById('dice5rnd').innerHTML = dice5rnd;
document.getElementById('dice6rnd').innerHTML = dice6rnd;
document.getElementById('dice7rnd').innerHTML = dice7rnd;
document.getElementById('dice8rnd').innerHTML = dice8rnd;
document.getElementById('dice9rnd').innerHTML = dice9rnd;
document.getElementById('dice10rnd').innerHTML = dice10rnd;
document.getElementById('dice11rnd').innerHTML = dice11rnd;
document.getElementById('dice12rnd').innerHTML = dice12rnd;
document.getElementById('dice13rnd').innerHTML = dice13rnd;
document.getElementById('dice14rnd').innerHTML = dice14rnd;
document.getElementById('dice15rnd').innerHTML = dice15rnd;
document.getElementById('dice16rnd').innerHTML = dice16rnd;
document.getElementById('demo').innerHTML = letters;
function addLetter() {
letters.push(dice1rnd);
document.getElementById('demo').innerHTML = letters;
}
Are you trying to do something like this?
You don't need nearly so many variables — use arrays, map, and forEach loops instead.
Also, your random only gets calculated once, so it will always be the same. If you put it in a function (() => ...) it becomes callable (random()) so you can generate many different values.
const random = () => Math.floor(Math.random() * 6);
const dice = [
['R', 'I', 'F', 'O', 'B', 'X'],
['I', 'F', 'E', 'H', 'E', 'Y'],
['D', 'E', 'N', 'O', 'W', 'S'],
['U', 'T', 'O', 'K', 'N', 'D'],
['H', 'M', 'S', 'R', 'A', 'O'],
['L', 'U', 'P', 'E', 'T', 'S'],
['A', 'C', 'I', 'T', 'O', 'A'],
['Y', 'L', 'G', 'K', 'U', 'E'],
['Q', 'B', 'M', 'J', 'O', 'A'],
['E', 'H', 'I', 'S', 'P', 'N'],
['V', 'E', 'T', 'I', 'G', 'N'],
['B', 'A', 'L', 'I', 'Y', 'T'],
['E', 'Z', 'A', 'V', 'N', 'D'],
['R', 'A', 'L', 'E', 'S', 'C'],
['U', 'W', 'I', 'L', 'R', 'G'],
['U', 'W', 'I', 'L', 'R', 'G'],
]
const randomize = () => {
const results = dice.map(die => die[random()])
document.querySelectorAll('.result').forEach((el, idx) => {
el.textContent = results[idx]
})
}
randomize()
document.querySelector('#btn').addEventListener('click', randomize)
.row {
display: flex;
font-family: monospace;
}
.result {
width: 2em;
height: 2em;
}
<div class="row"> <div class="result"></div><div class="result"></div><div class="result"></div><div class="result"></div></div><div class="row"> <div class="result"></div><div class="result"></div><div class="result"></div><div class="result"></div></div><div class="row"> <div class="result"></div><div class="result"></div><div class="result"></div><div class="result"></div></div><div class="row"> <div class="result"></div><div class="result"></div><div class="result"></div><div class="result"></div></div>
<button id="btn">Randomize</button>
To directly address your concern, you can use target prop of the event that is passed to your method to make it dynamic.
https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event
example:
function addLetter (event) {
console.log(event.target.innerHTML) // => should print contents of clicked div.
}
For school I need to make a script that prints 3 times something with 5 random letters. "ajshw kcmal idksj"
I have made this:
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z'];
var random = myArray[Math.floor(Math.random() * myArray.length)];
document.write('<br>' + random);
But this only prints one letter. How can it print 5 letters 3 times?
Iterate 5 times to generate each word with 5 letters and iterate 3 times to generate three words. You can use for loop to generate the words or you can use array#map to generate the words and using array#join you can join them.
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
random = [...Array(3)]
.map(_ => [...Array(5)].map(_ => myArray[Math.floor(Math.random() * myArray.length)]).join(''))
.join('<br>');
document.write(random);
What about just making a nested loop:
const myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z'
];
const length = myArray.length;
const numStrings = 3;
const numLetters = 5;
for (let i = 0; i < numStrings; i++) {
let string = "";
for (let j = 0; j < numLetters; j++) {
let letter = myArray[Math.floor(Math.random() * length)];
string += letter;
}
console.log(string);
}
A simple way would be to simply generate that single letter multiple times with a loop. A way to do this would go as follows:
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z'];
var phrase = "";
for (var x = 0; x < 3; x++) {
for (var y = 0; y < 5; y++) {
phrase = phrase + myArray[Math.floor(Math.random() * myArray.length)];
}
phrase = phrase + " ";
}
console.log(phrase)
var alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
var letters = document.createElement("ul");
letters.innerHTML = alphabet;
// This is to split the array "alphabet" into individual strings
var separatedLetters = document.getElementById("letters");
separatedLetters.appendChild(letters);
this is the code I used to attempt to split the string,
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
and that is how it appeared on my web page, it displays as one whole string instead of each letter being a string.
Something like the follow? Since you are using an unordered list, I am assuming you would want each character on its own bullet
var alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
var ul = document.createElement("ul");
for(var i = 0; i < alphabet.length; ++i) {
var li = document.createElement("li");
li.innerText = alphabet[i];
ul.appendChild(li);
}
document.body.appendChild(ul);
Here an example:
var alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
var string = alphabet.join("");// <--- array to string ABCDEFGHIJKLMNOPQRSTUVWXYZ
console.log(string);
var alphabet = string.split("");// <--- string to array
console.log(alphabet);
As mentioned, you should wrap every letter with li and append each element to the list.
Additionally, in order not to cause unnecessary reflows, you can utilize Document.createDocumentFragment()
HTML:
<div id="letters"></div>
JS:
var alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
var separatedLetters = document.getElementById("letters");
var fragment = document.createDocumentFragment();
fragment.appendChild(document.createElement('ul'));
alphabet.forEach(letter => {
var li = document.createElement('li');
li.textContent = letter;
fragment.childNodes[0].appendChild(li);
});
separatedLetters.appendChild(fragment);
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
My Array:
var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
Set Function to Button:
var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
for (var idx = 0; idx < alphabet.length; idx++) {
var bttn = document.createElement("button");
bttn.innerText = alphabet[idx];
bttn.onclick = function() {
this.disabled = true;
checkIfWordContainLetter(alphabet[idx]);
}
document.getElementById("hangmanContent").appendChild(bttn);
}
function checkIfWordContainLetter(letter) {
alert(wordToGuess);
alert(letter);
}
Causes undefined when I pass alphabet[idx] as parameter but if I pass for example 'a' it alerts a.
Try below code:
var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
for(var idx=0;idx<alphabet.length;idx++)
{
var bttn = document.createElement("button");
bttn.innerText = alphabet[idx];
bttn.onclick = function () {this.disabled=true;
checkIfWordContainLetter(this.innerText);
}
document.getElementById("hangmanContent").appendChild(bttn);
}
function checkIfWordContainLetter(letter)
{
alert(letter);
alert(letter);
}
<body>
<div id="hangmanContent"></div>
</body>
This is a issue related to scopes.
When you click the button, idx is equal to 26, because the for already ended, this index doesn't exists on array.
You can simple correct this changing var idx to let idx, but note that this is implemented only on modern browsers.
A legacy solution could be:
for (var idx = 0; idx < alphabet.length; idx++) {
var bttn = document.createElement("button");
bttn.innerText = alphabet[idx];
bttn.onclick = (function (index) {
return function () {
this.disabled = true;
checkIfWordContainLetter(alphabet[index]);
}
} (idx));
document.getElementById("hangmanContent").appendChild(bttn);
}
Read: JavaScript closure inside loops – simple practical example
Here is solution:
var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
for(var idx=0;idx<alphabet.length;idx++)
{
var bttn = document.createElement("button");
bttn.innerText = alphabet[idx];
bttn.onclick = function (idx)
{
this.disabled=true;
checkIfWordContainLetter(alphabet[idx]);
}.bind(this, idx);
document.getElementById("hangmanContent").appendChild(bttn);
}
function checkIfWordContainLetter(button)
{
//alert(wordToGuess);
alert(button.innerText);
}
You should understand javaScript closure.
When you clicked one of those buttons, the event handler will be excuted. You exposed the idx in the checkIfWordContainLetter(alphabet[idx]) to be 1,2,3,4,.....However, it will always be (alphabet.length + 1). They all refer to the same place in memory.