understanding Javascript recursion - javascript

I am trying to wrap my head around recursive functions, and I do not understand the output (this example is from John Resig's 'Javascript Ninja' book):
var ninja = {
chirp: function chirp(n) {
return (n > 1) ? chirp(n-1) + "-chirp"+n : "chirp"+n;
}
}
$('#hello').html(ninja.chirp(8));
and the output:
chirp1-chirp2-chirp3-chirp4-chirp5-chirp6-chirp7-chirp8
Why is the output of n increasing instead of decreasing? It seems to me that the output would count down from 8 instead of up from 1.
http://jsfiddle.net/9xq7j6y8/1/

If you call chirp(1) the result will be "chirp1".
If you call chirp(2) the result will be chirp(1) + "-chirp2", i.e. "chirp1-chirp2".
If you call chirp(3) the result will be chirp(2) + "-chirp3", i.e. "chirp1-chirp2-chirp3".
As you see, the function calls itself to get the output for the lower numbers, and adds the highest number last.

It is counting down from 8, but the output is getting appended to the beginning of the string, and then you're reading the output from left to right.
If you saw the output as it was being built, it would look like:
-chirp8
-chirp7-chirp8
-chirp6-chirp7-chirp8
...
chirp1-chirp2-chirp3-chirp4-chirp5-chirp6-chirp7-chirp8
Since you only see the final output, it shows up in ascending order.

Related

JS: += is returning a weird result

I asked this question previously and it got redirected (and treated as answered) to this question - "Adding two numbers concatenates them instead of calculating the sum".
But it did not help me solve it, I did try parseInt, Number(), and putting + in front of my number.
So here is my question again, but before I think I need to specify that I am using +=, not just +.
I used this function to add 5 to a number in a p element:
function add5() {lifeTotal.textContent += 5;}
I have a similar function that subtracts 5 to that same number:
function minus5() {lifeTotal.textContent -= 5;}
Now my problem is that while the subtracting function works as expected, the adding one just puts 5 at the right side of the number. So if the number was 10, it would return 105, as if both numbers were actually strings and not numbers... while the subtracting function works normally and treats numbers as numbers...
It turns me crazy. I just learnt this += thing and I really don't think I used it wrong...
So my solution is to instead use ++ five times, like so:
function add5() {lifeTotal.textContent ++; lifeTotal.textContent ++; lifeTotal.textContent ++; lifeTotal.textContent ++; lifeTotal.textContent ++;}
It works, but it seems to me this is not the shortest way to write this.
The app I am writing is adding or subtracting by calling the corresponding function with an onclick="function()" in html button tags.
What is happening? What is the shortest way to write this?
Thanks!
Thanks to #aerial301 for this answer:
lifeTotal.textContent = +lifeTotal.textContent + 5
It works. I assume that the + in front of my Var lifeTotal is converting the DOM content targeted by the .textContent to a number, which let JS see 2 numbers instead of a string and the number 5.

How to access the first two digits of a number

I want to access the first two digits of a number, and i have tried using substring, substr and slice but none of them work. It's throwing an error saying substring is not defined.
render() {
let trial123 = this.props.buildInfo["abc.version"];
var str = trial123.toString();
var strFirstThree = str.substring(0,3);
console.log(strFirstThree);
}
I have tried the above code
output of(above code)
trial123=19.0.0.1
I need only 19.0
How can i achieve this?
I would split it by dot and then take the first two elements:
const trial = "19.0.0.1"
console.log(trial.split(".").slice(0, 2).join("."))
// 19.0
You could just split and then join:
const [ first, second ] = trial123.split('.');
const result = [ first, second ].join('.');
I have added a code snippet of the work: (explanation comes after it, line by line).
function getFakePropValue(){
return Math.round(Math.random()) == 0 ? "19.0.0.1" : null;
}
let trial123 = getFakePropValue() || "";
//var str = trial123.toString();
// is the toString() really necessary? aren't you passing it along as a String already?
var strFirstThree = trial123.split('.');
//var strFirstThree = str.substring(0,3);
//I wouldn't use substring , what if the address 191.0.0.1 ?
if(strFirstThree.length >= 2)
console.log(strFirstThree.splice(0,2).join("."));
else
console.error("prop was empty");
Because you are using React, the props value was faked with the function getFakePropValue. The code inside is irrelevant, what I am doing is returning a String randomly, in case you have allowed in your React Component for the prop to be empty. This is to show how you an create minimal robust code to avoid having exceptions.
Moving on, the following is a safety net to make sure the variable trial123 always has a string value, even if it's "".
let trial123 = getFakePropValue() || "";
That means that if the function returns something like null , the boolean expression will execute the second apart, and return an empty string "" and that will be the value for trial123.
Moving on, the line where you convert to toString I have removed, I assume you are already getting the value in string format. Next.
var strFirstThree = trial123.split('.');
That creates an array where each position holds a part of the IP addrss. So 19.0.0.1 would become [19,0,0,1] that's thanks to the split by the delimiter . . Next.
if(strFirstThree.length >= 2)
console.log(strFirstThree.splice(0,2).join("."));
else
console.error("prop was empty");
This last piece of code uses the conditional if to make sure that my array has values before I try to splice it and join. The conditional is not to avoid an exception, since splice and join on empty arrays just returns an empty string. It's rather for you to be able to raise an error or something if needed. So if the array has values, I keep the first two positions with splice(0,2) and then join that array with a '.'. I recommend it more than the substr method you were going for because what if you get a number that's 191.0.0.1 then the substr would return the wrong string back, but with splice and join that would never happen.
Things to improve
I would strongly suggest using more human comprehensible variables (reflect their use in the code)
The right path for prop value checking is through Prop.Types, super easy to use, very helpful.
Happy coding!

How to swap two numbers using javascript function with one parameter

My Requirement is
I want to display this output when I gave a(0) the output should come 5 and when I gave a(5) the output should come 0.
a(0) = 5
a(5) = 0
like this
Hint:
Using this function
function A(num){}
like this
Please Help me how to do this I'm new in JS
Please give me different kind of solutions its more useful to my career.
function swap (input) {
if( input == 0)
return 5;
return 0;
}
i think there is no description needed
I think I see what you are getting at.
You want to input one variable into a function, and return another variable that is not defined yet. Then you want to define that variable by inputting it into the same function, and get the first input as the output. And so you should end up with 2 outputs.
Now this is technically impossible, because there are undefined variables at play. However, programming is about imagination and I think I have a solution (it's technically a hack but it will work):
var i = 1;
var output1;
var output2;
function swap(input) {
function func1(input) {
output2 = input;
i++;
}
function func2(input) {
output1 = input;
i = 1;
alert(String(output1) + "\n" + String(output2));
}
if (i === 1) {
func1(input);
}
else if (i === 2) {
func2(input);
}
}
while(true) {
swap(prompt("Enter your first input (this will be your second output):"));
swap(prompt("Enter your second input (this will be your first output):"));
}
The swap function goes back and forth between the values 1 and 2 in the variable i. That is how it keeps track of first or second inputs and their exact opposite outputs. The input, or parameter of the swap function is whatever the user types into the prompt boxes. Feel free to make it user-friendly, this is just the dirty code behind it. The reason they are outputted together is because the second input is undefined, and so the machine cannot guess what you were going to input. So first my little program collects all the data and just reverses the order when it is time to output. But to the user who knows nothing about JavaScript and what is going on underneath the hood, this would work perfectly in my opinion.
This should work for any data types inputted, I tested it myself with objects, strings, numbers, and arrays. Hope this helps!!
Shorter alternative to #mtizziani's answer:
let swap = x => !x * 5 // yes this is all
console.log(swap(0));
console.log(swap(5));
We toggle the input, so x is now 1 or 0
We multiple by 5.
Job done.

How to print on same line using console.log() in JavaScript?

I want to print a list (var lst=[1,2,3,4,5]) using a loop on the same line. Can I do that in JavaScript ?
Well you can achieve this by doing this. Make an empty string variable and then concatenate each array value to it, then print it out. This will work
var lst = [1,2,3,4,5];
var output = "";
for(var i =0; i <= lst.length; i++){
output += lst[i] + " ";
}
console.log(output);
In NodeJS and as long as you didn't change your standard output you can use process.stdout.write("Something here") as the standard output of your application is terminal (console).
process.stdout.write("Hello ")
process.stdout.write("World")
process.stdout.write("!")
Hello world!
Console.log doesn't allow you to print in the same line. However the task that you are trying to do can be done using the below:
console.log(lst.join(" "))
Output: 1 2 3 4 5
You could use Function#apply or spread syntax ....
var list = [1, 2, 3, 4, 5];
console.log.apply(null, list); // traditional
console.log(...list); // ES6
The exact behavior of console.log is not specified by ECMAScript, so it varies from implementation to implementation, but it is intended to be used for logging events. The fact that each event usually becomes a single line in a web browser's console window led it to be the Node.js equivalent of "println", but outside the context of a specific implementation its behavior is not predictable.
You can pass multiple parameters to log, in which case most (but not all) implementations will print them all out on the same line separated by whitespace. So if you're using one of those implementations, and you have a list and just want all the elements on one line separated by space, you can use apply to call the method as if each element of the list was a separate argument:
console.log.apply(console, lst);
Caveat: if the first argument is a string that contains what look like Formatter format control sequences (%s, etc.), it will be parsed as such and the remaining arguments used to fill in those slots.
But the most reliable way to achieve the desired result is to build a single string yourself representing what you want the final line to look like, and then call console.log exactly once with that string as the argument.
You could do it easily by using the join() function which can be used on any array in JavaScript!
For example:
var lst = ["check","word","3","could","hello"]
console.log(lst.join())
source-code:
https://jsfiddle.net/Lpdurxsb/

Javascript Unnecessarily Compact Array Operations

So, for my own knowledge, and because I love looking at things from a different perspective...
I have the following bite of Javascript code, which for this problem's intents and purposes will only ever receive strings formatted like this: "wordone wordtwo":
function inName(inputName) {
return inputName.split(" ")[1].toUpperCase();
}
However, this only returns half of what I want ("WORDTWO"). I desire to return the original string with a single change: the space-separated second word returned through the toUpperCase(); and then re-concatenated to the untouched first word.
I also want to unnecessarily run all of the operations on the return line. My brain says this is possible, given how as the compiler reads the line from left to right and makes adjustments to the available member functions based on what has resolved. Also everything in Javascript is an object, correct?
Help me out for my own curiosity's sake, or bash me over the head with my own misconceptions.
Here is a solved version of the above question using 'normal' statements:
function inName(inputName) {
var nameArray=inputName.split(" ");
nameArray[1]=nameArray[1].toUpperCase();
return nameArray.join(" ");
}
One line with substr, indexOf and a variable on the fly ;-)
function inName(inputName) {
return inputName.substr(0, (index = inputName.indexOf(' '))) + inputName.substr(index).toUpperCase();
}
Here's another option which avoids the regular expression:
function inName(inputName) {
return inputName.split(' ').map(function(v,i){return i?v.toUpperCase():v;}).join(' ');
}
This does the same split as the original code, then maps the parts to a function which returns the value at index 0 unchanged but the value at index 1 in upper case. Then the two results are joined back together with a space.
As others have said, a longer, clearer version is better in practice than trying to come up with a clever one-liner. Defining a function inside the return statement feels like cheating anyway ;-)
Something like this almost seems like it belongs on Code Golf, but here's my take:
function inName(inputName) {
return inputName.replace(/ .*/,function(m) {return m.toUpperCase();});
}
Interesting. Here is my take on the problem
function justDoIt(str){
return [str = str.split(" ") , str.pop().toUpperCase()].join(" ");
}
Creates a new array, str is split and reassigned as an array, and the first item of the new array, then the second new array item pops the last word, makes it uppercase, puts it into the new array. Then joins the array [["wordOne"],"WORDTWO"].join(" ")

Categories

Resources