Source of "undefined" showing in console - javascript

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");

Related

I want to sort my words from arr by 2nd letter of each word according to my given pattern

/*
pattern:
e,b,c,d,i,f,g,h,o,j,k,l,m,n,u,p,q,r,s,t,a,v,w,x,y,z
I want to sort my words from arr by 2nd letter of each word according to my given pattern.
['aobcdh','aiabch','obijkl']
#output should be:
obijkl
aiabch
aobcdh
*/
// I tried this way:
let pattern = ['e', 'b', 'c', 'd', 'i', 'f', 'g', 'h', 'o', 'j', 'k', 'l', 'm', 'n', 'u', 'p', 'q', 'r', 's', 't', 'a', 'v', 'w', 'x', 'y', 'z']
let arr = ['aiabch', 'aobcdh', 'obijkl', 'apcsdef', 'leeeeeeeeeeeeeeee']
let refArr = []
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < pattern.length; j++) {
if (pattern[j] === arr[i][1]) {
refArr.push(j)
}
}
}
console.log(refArr)
// now what next?
You can use the sort method and the indexOf function
let pattern = ['e', 'b', 'c', 'd', 'i', 'f', 'g', 'h', 'o', 'j', 'k', 'l', 'm', 'n', 'u', 'p', 'q', 'r', 's', 't', 'a', 'v', 'w', 'x', 'y', 'z']
let arr = ['aiabch', 'aobcdh', 'obijkl', 'apcsdef', 'leeeeeeeeeeeeeeee']
const newArr = arr.sort((a, b) => pattern.indexOf(a[1]) - pattern.indexOf(b[1]))
console.log(newArr)
You could generate an object with the order values and sort by this values.
If necessary convert the key to lower case and/or take a default value for sorting unknown letters to front or end.
const
pattern = 'ebcdifghojklmnupqrstavwxyz',
array = ['aobcdh', 'aiabch', 'obijkl'],
order = Object.fromEntries(Array.from(pattern, (l, i) => [l, i + 1]));
array.sort((a, b) => order[a[1]] - order[b[1]]);
console.log(array);
Also, you can try this if you does not know Array methods.
let pattern = ['e', 'b', 'c', 'd', 'i', 'f', 'g', 'h', 'o', 'j', 'k', 'l', 'm', 'n', 'u', 'p', 'q', 'r', 's', 't', 'a', 'v', 'w', 'x', 'y', 'z'], arr = ['aiabch', 'aobcdh', 'obijkl', 'apcsdef', 'leeeeeeeeeeeeeeee'], refArr = []
arr.forEach(a => pattern.includes(a[2]) ? refArr.push(a) : null)
console.log(refArr)
You must reverse your cross loops:
for(let i = 0; i < pattern.length; ++i) {
for(let j = 0; j < arr.length; ++j) {
if(pattern[i] === arr[j][1]) refArr.push(arr[j]);
}
}

Pick 5 random letters from array

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)

How do I split an array with 26 different string values, that appear as 1 string on a webpage?

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);

Passing Array Value as Parameter causes undefined [duplicate]

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.

JavaScript: Why This Code Doesn't Work?

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');

Categories

Resources