NaN appearing because of quotes within split property - javascript

I'm sorry if this has already been answered here, but I'm not entirely sure what to even look for. I've recently started learning to code as something I've seen as enjoyable. I used a website and it told me that I had learned all I needed to about javascript (though I don't think that's true). To get some practice and a better handle on it I decided to do some challenges. I was working on one and got it mostly right. It said to reverse any input string (I was not required to code how to input, at least I think). The input is str. I've gotten it to reverse all of the characters, including punctuation, except quotations. To input, the phrase is required to be in quotations. In my result, instead of having quotations, it has a NaN before the phrase.
Here is the code I made
function FirstReverse(str) {
var strL = str.length;
var strS = str.split("");
for(var i = 0; i <= str.length; i++){
var strC = strC + strS[strL];
strL = strL -1;
}
// code goes here
return strC;
}
// keep this function call here
FirstReverse(readline());
and if I input "Hello, world", I get NaNdlrow ,olleH. I'm new, so it would help if this can be put into simpler terms. what you see in the code is about the most advanced stuff I know.
Thank you for your time.

The reason you're getting NaN is because you never initialized strC, and you're also accessing outside the strS array.
You should initialize strC to an empty string.
And to prevent accessing outside the array, initialize strL to str.length-1, since array indexes go from 0 to length-1.
And the loop should repeat when i < str.length, not i <= str.length, otherwise you'll go past the beginning as well.
function FirstReverse(str) {
var strL = str.length-1;
var strS = str.split("");
var strC = "";
for(var i = 0; i < str.length; i++){
strC = strC + strS[strL];
strL--;
}
// code goes here
return strC;
}
// keep this function call here
console.log(FirstReverse("abcdef"));

You need to switch around your for loop and define strC to be blank. Since strC is undefined the first time you run strC = strC + strS[i]; is causing the NaN problem. Also, it seems easier to start at str.length and decrement to 0. Lastly, as previously posted there's no need for the call to split.
function FirstReverse(str) {
var strL = str.length-1;
var strC = "";
for(var i = strL; i >= 0; i--){
strC = strC + str[i];
}
// code goes here
return strC;
}

function FirstReverse(str)
{
var strC = "";
var strS = str.split("");
for(var i = str.length-1; i >= 0 ; i--) {
strC += strS[i];
}
return strC;
}
FirstReverse("hello, world");

You have two simple errors in your code that are leading you to that "NaN" at the beginning of your string.
1) You need to declare your strC variable outside of the loop so that it has an initial value of empty string, var strC = "";. Currently the first time through your loop it is undefined.
2) The second mistake is that the variable you are using for indexing the values, strL, starts off as the length of the input string, when it should be one less. This is because the array is zero-indexed so the last item in the array is at strS[strS.length - 1]. (strS.length and str.length in your code are the same)
For example: The string "abc" has a length of 3 and so strS would be equal to ["a", "b", "c"] (also with a length of 3) and so strS[0] is equal to "a" and strS[2] is equal to "c". But since you are starting from the length itself instead of length - 1, on the first iteration of the loop you are asking for strS[3] which is undefined.
So for this issue, subtract one from the length when you initialize the variable: var strL = str.length - 1;
The reason this is resulting in the letters "NaN" is because in JavaScript NaN is a special value that means "Not a Number" and is represented when converted to a string as "NaN".
On your first loop strC is undefined (the first issue) and strS[strL] is undefined (the second issue) so your statement translates to var strC = undefined + undefined;. In JavaScript undefined + undefined is treated as a mathematical expression and results in NaN.
So at the start of the second time through the loop, strC is equal to NaN and strL is now pointing to the last item in the array so you get the "d" from the end of "Hello, world". So your statement translates to strC = NaN + "d";, the NaN is converted to a string since + is treated as the string concatenation operator and you end up with "NaNd" and then the rest of your loop runs through just fine.
There are some better ways of doing what you are trying to accomplish, but as you learn and practice more you'll figure them out and now you know why your code is doing what it is and where this weird "NaN" nonsense is coming from. :)
Also, I think that you seem confused as to why your input has quotes but not the output. You are inputting a string with the content Hello, world but strings are represented in code surrounded by quotes ala "Hello, world" so you shouldn't get quotes in the output.
Oh, and just for clarity, your code corrected looks like this:
function FirstReverse(str) {
var strL = str.length - 1;
var strS = str.split("");
var strC = "";
for (var i = 0; i <= str.length; i++) {
strC = strC + strS[strL];
strL = strL - 1;
}
return strC;
}
But there are simpler ways such as counting down from the input length using the loop counter itself:
function FirstReverse(str) {
var strS = str.split("");
var strC = "";
for (var i = str.length - 1; i >= 0; i--) {
strC = strC + strS[i];
}
return strC;
}
And even accessing the string itself without bother with split:
function FirstReverse(str) {
var strC = "";
for (var i = str.length - 1; i >= 0; i--) {
strC = strC + str[i];
}
return strC;
}
Or even just using some built-in string and array functions:
function FirstReverse(str) {
return str.split("").reverse().join("");
}

I think I managed to find the mistake. Change the for cycle from
for(var i = 0; i <= str.length; i++) to for(var i = 0; i < str.length; i++). Let me know what happened after the changes were done!

Related

TypeError: Cannot read property 'length' of undefined | Finding the shortest word in a string | Codewars Challenge

I am currently trying to create a function that looks for the shortest word in a string of words.
Problem: I am getting the following error
TypeError: Cannot read property 'length' of undefined
at findShort
at Test.describe._
at /runner/frameworks/javascript/cw-2.js:152:11
at Promise._execute
at Promise._resolveFromExecutor
at new Promise
at Object.describe
at /home/codewarrior/index.js:24:10
at /home/codewarrior/index.js:28:5
at Object.handleError
Here is my code
findShort("turns out random test cases are easier than writing out basic ones");
function findShort(s){
let array = s.split(" ");
let shortestWord = array[0];
for (i = 0; i < array.length; i++) {
let str = array[i + 1];
if (shortestWord.length > str.length) {
shortestWord = str.length;
}
}
return shortestWord;
}
I see two problems:
The line let str = array[i + 1] is going to result in undefined on the last run of your loop. That's because on the last run, i is one less than the array length, so i + 1 is therefore out of the array bounds. To compensate for that, consider changing the loop condition to i < array.length - 1.
Second, you are assigning the word length to the shortestWord variable, where I think you meant to assign the word itself to that.
Taking those two changes into account, you could modify your code like so:
function findShort(s) {
let array = s.split(" ");
let shortestWord = array[0];
for (i = 0; i < array.length - 1; i++) { // -1 here to compensate for the +1 on the next line.
let str = array[i + 1];
if (shortestWord.length > str.length) {
shortestWord = str; // Just assign the word itself to this variable, not the length of it.
}
}
return shortestWord;
}
const result = findShort("turns out random test cases are easier than writing out basic ones");
console.log(result);
I believe this is a more concise way of doing what you're looking for:
console.log(findShort("turns out random test cases are easier than writing out basic ones"));
function findShort(s){
let input = s;
let array = input.split(" ");
var shortest = array.reduce((shortestWord, currentWord) => {
return currentWord.length < shortestWord.length ? currentWord : shortestWord;
}, array[0]);
return shortest;
}
https://jsfiddle.net/02z5oyh1/

How to make element in Array change its' place

I'm beginner in JS. I've tried to understand Caesar Cipher ROT13, but it was too complicated for me. So I've tried to write my own code. Here it is below:
function encrip() {
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 str = "Ni Hao";
var string = str.toUpperCase();
for (var i = 0; i < string.length; i++) {
for (var k = 0; k < alphabet.length; k++) {
if(string.charAt(i) == alphabet[k]) {
/* console.log(string.charAt(i) + ' ' + alphabet.indexOf(alphabet[k])); */
}
}
}
}
encrip();
But I am stuck. How to do:
1. Get value from var str and then access to var alphabet , after change each letter from var str value to next 3 from alphabet (var str each element's current position would be changed) For example: Input: Ni Hao ==> output: QL KDR
2. Create universal code, I mean, not only for changing position by 3, but when I give value '5', each element would be changed by next 5 positions from alphabet. So output can be changed when I change its' value
I hope I explained everything clearly. Thanks everyone in advance for help!!
you can use the following function to encrypt english words, the 1st parameter is the string to encrypt and the 2nd for shifting
function encryp(str,pos){
var alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var strUC=str.toUpperCase();
var enc="";
for(var i=0;i<strUC.length;i++){
if(strUC.charAt(i)!=" "){
enc+=alpha.charAt((alpha.indexOf(strUC.charAt(i))+pos)%26)
}
else{
enc+=" "
}
// in your case pos=3
}
return enc;
}
console.log(encryp("NiHao",3));
You don't need two for loops to do this. Iterate over the input string and find the index of each character in the alphabet array, if found add the shift to it to get the encrypted character.
To handle overflow use the modulus operator to cycle through the array.
Also I assume that you are not going use any special symbols to do the encryption.
function encrip(string, shift) {
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"];
string = string.toUpperCase();
let arr = [];
for (var i = 0; i < string.length; i++) {
let char = alphabet.indexOf(string[i]) !== -1 ? alphabet[(alphabet.indexOf(string[i]) %26) + shift] : " ";
arr.push(char);
}
let encryp = arr.join("");
console.log(encryp);
return encryp;
}
encrip("Ni Hao", 3);
First of all, instead of your inner for loop scanning the whole alphabet array, you can use the built-in function indexOf:
alphabet.indexOf('K') // returns 10
Secondly, you'll want to build up your enciphered string in a separate variable. For each letter, get the index of that letter in the alphabet, add your cipher offset parameter to that index and add the resulting letter from the alphabet to your new string. An important step is that when you add to the index of the letter, you want to make sure the resulting index is within range for the alphabet array. You can do that using the % (modulo) operator, which will wrap high values back round to the start of the array. In full:
function encipher(input, offset) {
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 str = input.toUpperCase();
var result = '';
for (var i = 0; i < str.length; i++) {
letterIndex = alphabet.indexOf(str.charAt(i));
if (letterIndex === -1) {
result += str[i]; // if the letter isn't found in the alphabet, add it to the result unchanged
continue;
}
cipheredIndex = (letterIndex + offset) % alphabet.length; // wrap index to length of alphabet
result += alphabet[cipheredIndex];
}
console.log(result);
}
encipher('Ni Hao', 5); // output: 'SN MFT'

When reversing string, I'm getting a NaN at the end. Javascript [duplicate]

This question already has answers here:
'Length' Property Undefined while iterating Array
(3 answers)
Closed 6 years ago.
I'm trying to reverse a string, and it does work, but when I store the userInput[i] into the result variable, I'm getting NaN at the end of the string.
//variables
var userInput, result;
userInput = prompt("Enter a string that you want reversed: ");
for (var i = userInput.length; i >= 0; i--) {
result += userInput[i];
}
console.log("Your string: \n" + result);
You start the loop from userInput.length which is a wrong index because userInput[userInput.length] is undefined. What you need to do is start from userInput.length - 1 like this (and don't forget to initialize result to empty string before starting to accumulate the result):
result = "";
for (var i = userInput.length - 1; i >= 0; i--) {
result += userInput[i];
}
NOTE: When going up an array, we don't actually reach the point when we access the userInput.length index (i.e. userInput[userInput.length]) because usually the condition for the loop is i < userInput.length which fail as soon as i is equal to userInput.length. When going downwards an array, one should keep track of what are the indexes allowed.
NOTE 2: It is safer to use string.charAt(index) rather than string[index]. Learn why here.
You are better off, by reversing a string in JavaScript using something like below:
'YOURSTRING'.split('').reverse().join('');
e-g
'abcdef'.split('').reverse().join('') will give you fedcba
try this
var userInput, result = ""; // initialize this first
userInput = prompt("Enter a string that you want reversed: ");
for (var i = userInput.length - 1; i >= 0; i--) {
result += userInput[i];
}
console.log("Your string: \n" + result);
this problem consists of 2 smaller problems.
First problem:
"result" is not initialized so it contains "undefined" which messes with the string later on. Initialize it to be an empty string so JavaScript knows it should handle it as a string since the "+"-operator is overloaded to handle addition and string concatenation.
Second problem
The index of the userInput string reaches from 0 - (userInput.length - 1), so change the loop accordingly.
var userInput, result = ""; // initialize this first
userInput = prompt("Enter a string that you want reversed: ");
// initialize i with (userInput.length - 1) since the index ends there
for (var i = userInput.length - 1; i >= 0; i--) {
result += userInput[i];
}
console.log("Your string: \n" + result);
The length property of String returns the letters' count whereas the index of an Array starts from 0. So, your issue could be resolved by reducing the string length by 1 i.e. userInput.length - 1.
var userInput, result="";
userInput = prompt("Enter a string that you want reversed: ");
for (var i = userInput.length - 1; i >= 0; i--) {
result += userInput[i];
}
console.log("Your string: \n" + result);
Get you string.Split it into array.reverse your array and join.Finally you will get the reversed string.
var userInput, result = ""; // initialize this first
userInput = prompt("Enter a string that you want reversed: ");
result = userInput.split("").reverse().join("");
console.log("Reversed string: \n" + result);

Printing in Javascript

i have a question that seems basic but i can't seem to figure it out.
Write a program that takes the value of a variable called “input” (declared as any whole number at the top of your program) and outputs a square made of asterisks () as large as the number (input). For example, if the “input” is declared with the value 5, your program would display a square made of 25 asterisks() – ie ; 5 asterisks () high, by 5 asterisks () long.
The code i've come up with so far is below. I don't really understand how to make a string continuously print. If i did star = i then it turns into numbers and will print the numbers. So how do i make it so they connect? I also can't figure out where i should put the new line. console.log(star "\n"); gives me an error. Please help :)
var input = 2;
var star = "*";
var i = 0;
do {
console.log(star);
i++;
} while (i < input);
You can use String.repeat() (ES6 only) along with \r\n to add new line
var input = 5,
star = "*",
str = [],
i = 0;
do {
str.push( Array(input).join(star) ); // use array(length).join
i++;
} while (i < input);
str = str.join("\r\n"); // add breaklines
console.log(str);
console.log Will output a single line to the console containing whatever you pass it as an argument. You are trying to print a line of n asterisks n times.
The first step you should take is constructing the string of asterisks. You can concatenate a string to another with the + operator:
var input = 2;
var star = "*";
var line = "";
for(var i = 0; i < input; i++) {
line = line + star;
}
Once you have constructed line you can then print it n times:
for(var i = 0; i < input; i++) {
console.log(line);
}
Hint: You could create an empty array and then create a loop ending at your wanted number of asterisks after which you will join all the members of the array together. (Writing the code here wouldn't help you much since you mentioned it's an homework).
You could approach this in two ways. If we call your input value n, then we can log either n strings each consisting of n stars, or we can log a single string, containing (n * n) stars, with line breaks after every nth star.
Below is an example of a function that could do this task.
function stars (input) {
var output = ''
for (var i = 0; i < input; i++) {
for (var j = 0; j < input; j++) {
output += '*'
}
output += '\n'
}
return output
}
You can use the repeat-function to print a character multiple times.
var input = 2;
var star = "*";
var i = 0;
while(i++ < input){
console.log(star.repeat(input));
}
This repeats the * character input times in input lines.

javascript string algorithm

Let's say I have a string variable called myString, and another string variable called myChar.
var myString = "batuhan"; // it's user input.
var myChar = "0"; // will be one character, always
What I need is, a function that returns all the combinations of myString and myChar.
Like:
"batuhan","batuha0n","batuh0an","batuh0a0n","batu0han","batu0ha0n","batu0h0an","batu0h0a0n","bat0uhan","bat0uha0n","bat0uh0an","bat0uh0a0n","bat0u0han","bat0u0ha0n","bat0u0h0an","bat0u0h0a0n","ba0tuhan","ba0tuha0n","ba0tuh0an","ba0tuh0a0n","ba0tu0han","ba0tu0ha0n","ba0tu0h0an","ba0tu0h0a0n","ba0t0uhan","ba0t0uha0n","ba0t0uh0an","ba0t0uh0a0n","ba0t0u0han","ba0t0u0ha0n","ba0t0u0h0an","ba0t0u0h0a0n","b0atuhan","b0atuha0n","b0atuh0an","b0atuh0a0n","b0atu0han","b0atu0ha0n","b0atu0h0an","b0atu0h0a0n","b0at0uhan","b0at0uha0n","b0at0uh0an","b0at0uh0a0n","b0at0u0han","b0at0u0ha0n","b0at0u0h0an","b0at0u0h0a0n","b0a0tuhan","b0a0tuha0n","b0a0tuh0an","b0a0tuh0a0n","b0a0tu0han","b0a0tu0ha0n","b0a0tu0h0an","b0a0tu0h0a0n","b0a0t0uhan","b0a0t0uha0n","b0a0t0uh0an","b0a0t0uh0a0n","b0a0t0u0han","b0a0t0u0ha0n","b0a0t0u0h0an","b0a0t0u0h0a0n"
Rules: myChar shouldn't follow myChar
How can I do that? Really my brain dead right now :/
It's possible to implement what you want using recursion.
// Example: allCombinations("abcd", "0") returns the array
// ["abcd", "abc0d", "ab0cd", "ab0c0d", "a0bcd", "a0bc0d", "a0b0cd", "a0b0c0d"]
function allCombinations(str, chr) {
if (str.length == 1)
return [str];
var arr = allCombinations(str.substring(1), chr);
var result = [];
var c = str.charAt(0);
for (var i = 0; i < arr.length; i++)
result.push(c + arr[i]);
for (var i = 0; i < arr.length; i++)
result.push(c + chr + arr[i]);
return result;
}
You may or may not have noticed this but this is basically counting in binary. If we define bit 0 to be the absence of myChar and bit 1 to be the presence of myChar, then the following sequence:
var myString = ".....";
var myChar = "1";
var sequence = [
".....1",
"....1.",
"....1.1",
"...1.."
];
is basically counting from 1 to 4 in binary:
var sequence = [
0b0000001,
0b0000010,
0b0000011,
0b0000100
];
Therefore, all you need is a for loop to count up to the bit amount of the length of the string plus 1 (because the position at the end of the string is also legal):
var len = Math.pow(2,myString.length+1);
for (var x = 0; x < len; x++) {
// x in binary is all the possible combinations
// now use the "1" bits in x to modify the string:
// Convert myString to array for easy processing:
var arr = myString.split('');
arr.push(""); // last position;
for (var i = myString.length; i >= 0; i--) {
if ((x >> i) & 0x01) { // check if bit at position i is 1
arr[i] = myChar + arr[i];
}
}
console.log(arr.join('')); // print out one combination
}
Of course, this works only for small strings of up to 31 characters. For larger strings you'd need to do the binary counting using things other than numbers. Doing it in a string form is one option. Another option is to use a bigint library such as BigInteger.js to do the counting.

Categories

Resources