How to make a JavaScript 'while' loop more elegant? - javascript

I've made a JavaScript 'while' loop to keep adding a random number from 1 to 10 to an array until the random number is 9 or 10.
function random() {
return Math.floor(Math.random() * (10)) + 1;
}
var array = [];
var element = 0;
while (element < 9) {
element = random();
if (element < 9) {
array.push(element);
}
}
console.log(array);
I have two questions.
How can I make the 'while' loop more elegant - without using (element < 9) two times?
How can I do this in a more elegant way, without using a 'while' loop?

To answer your first question, you can initialise element with a random value to begin with:
var element = random();
while (element < 9) {
array.push(element);
element = random();
}
This gets rid of the inner if.
To answer your second question, it doesn't get more elegant than this really. If you really want to use something else, you could use a do-while by changing around your code but really it's the same thing.
An even better alternative (I credit #NiettheDarkAbsol) for this, is to perform the assignment and check in one step:
while ((var element = random()) < 9) {
array.push(element);
}
You eliminate the need to even declare it outside, or call random() in more than one place.

Related

Explanation How Rectangle Recursion JavaScript works

I am a beginner in code world. I have troubles understanding recursion in JavaScript especially when it needs two or more looping. Like I want to print rectangle using recursion. I don't know completely how to make a base case, condition when it still executed. For examples, these codes below I use to print rectangle or holey rectangle.
function box(num) {
for (let i = 0; i < num; i++) {
let str = ''
for (let j = 0; j < num; j++) {
str += '*'
}
console.log(str)
}
}
box(5)
function holeBox (num) {
for(let i = 0; i < num; i++){
let str = ''
for(let j = 0; j < num; j++){
if(i == 0 || i == num -1 || j == 0 || j == num - 1) {
str += '*'
} else {
str += ' '
}
}
console.log(str)
}
}
holeBox (5)
Please help me to understand recursion, an explanation would be great. My goals are not only to solve those codes but also to understand how recursion works. I've searched there's no good source to learn recursion, or I just too dumb to understand. Thanks in advance
To understand how recursion works, just think of how you can split up what you want to accomplish into smaller tasks, and how the function can complete one of those tasks, and then call itself to do the next- and so on until it is finished. I personally don't think printing boxes is the best way to learn recursion, so imagine you wanted to search an array for a specific value; ignore JavaScript's indexOf()/find() functions or similar for now.
To do this using loops, its easy, just iterate over the array, and check every value:
//Returns the index of the first occurrence of a value in an array, or -1 if nothing is found
function search(needle, haystack) {
for (let i = 0; i < haystack.length; i++) {
if (haystack[i] == needle) return i;
}
return -1;
}
Doing this using recursion is easy as well:
function recursiveSearch(needle, haystack, i) {
if (i > (haystack.length - 1)) return -1; //check if we are at the end of the array
if (haystack[i] == needle) return i; //check if we've found what we're looking for
//if we haven't found the value yet and we're not at the end of the array, call this function to look at the next element
return recursiveSearch(needle, haystack, i + 1);
}
These functions do the same thing, just differently. In the recursive function, the two if statements are the base cases. The function:
Tests if the current element is out of bounds of the array (meaning we've already searched every element), and if so, returns -1
Tests if the current element is what we're looking for, and if so, returns the index
If neither of the statements above apply, we call this function recursively to check the next element
Repeat this until one of the base cases kicks in.
Note that recursive functions are usually called from other helper functions so that you don't have to pass the initial parameters to call the function. For example, the recursiveSearch() function above would be private, and it would be called by another function like this:
function search(needle, haystack) {
return recursiveSearch(needle, haystack, 0);
}
so that we don't have to include the third parameter when we call it, thus decreasing confusion.
Yes, even your box code can be turn into recursion but I don't think it will help you understand the concept of recursion.
If you really have to:
function getBox(arr, size) {
let length = arr.length;
if (length == size)
return arr; // recursion stop rule - if the size reached
for (let i = 0; i < length; i++)
arr[i].push("*"); // fill new size for all row
arr.push(new Array(length + 1).fill("*")); // add new row
return getBox(arr, size); // recursive call with arr bigger in 1 row
}
However, I believe #Gumbo answer explain the concept better then this...

For loop homework

I have homework and these are my instructions:
create javascript 06.js with a general function: addThemUp()
There is NO HTML page. There is NO EVENT HANDLER.
The function receives two parameters. They go between (..).
Use any names you want for the parameters but you could use descriptive names
Add all integers from the first parameter to the second.
All you need to do is use a for() loop and return the total.
Return the total of the integers. Use return because this is a general function.
Here is my code
function addThemUp(earlier,later) {
var total = 0;
for (i = 0; i <= earlier; i ++) {
total = total + 0;
};
return total;
};
For some reason this one is messing up bad. We were able to do this exact same thing with Count but adding up and array seems to be different. When I run it through the grader I'm only receiving 25% grade.
You need to make use of both earlier and later in your loop:
function addThemUp(earlier,later) {
var total = 0;
for (i = earlier; i <= later; i ++) {
total = total + i;
};
return total;
};
Shouldn't it be using
i <= later
As it would stop on the first value otherwise?
I'll point out two things that could help you on your way.
First: this line
total = total + 0;
Think about what it's doing for a bit.
total (which starts as 0) is adding... 0... to itself. ;)
Next, this line:
for (i = 0; i <= earlier; i ++) {
IIRC, earlier is the first of the two numbers you're concerned about.
That part of the for loop says "stop when this condition is met." ;)

Problems with the "+" and "-" operators

The problem is the - operator does not working (in 8th line). See my code below:
array = [0,0,0,0,3,0,0,0,0],
n = 0;
for(var i = 0; i < array.length; i++){
if(n < 9){ //the "n" variable there's only for don't crash the browser with a infinite loop
if(array[i] == 3){
array[i] = 0;
array[i - 1] = 3; //I believe that here is the problem
}
}
n++;
}
console.log(array);
So... I want to move the "3" value to the beginning of the array. But it only work if I use the + operator(in 8th line). Consequently, if I use the + one, the "3" value goes to the end of the array.
Anyone know why the - operator does not working in this case and the + works?
If you change line 8 to:
array[i+1] = 3;
then the number 3 will go all the way to the end of the array (well, beyond the end of the array and I'll be damned to find out what Javascript does then!). This is because the loop traverses the array in increasing order and the position i+1 will be checked right next.
On the other hand, with your current line 8, number 3 goes one position backwards (which has already been checked), so it doesn't go all the way to the beginning of the array, just one position. If you want it to go to all the way in the same fashion, you should reverse the loop (make it traverse the array in descending order of the position i).
What do you think happens when i is 0 and you do - 1?
In your first iteration of the loop, when i is zero, (i - 1) is -1, so you're trying to access array[-1], which is invalid.
Okay, instead of answering "Anyone know why the - operator does not working in this case and the + works?", I will answer what I think is the real question, as stated in the original post: I want to move the "3" value to the beginning of the array. I think this does what is desired:
var array = [0,0,0,0,3,0,0,0,0];
var first_val = 3;
var index = array.indexOf(first_val);
if (index > 0) {
array.splice(index, 1);
array.unshift(first_val);
}
console.log(array);
Inspired by this.
I want to move the "3" value to the beginning of the array
Use the correct answer provided in here. Then use .indexOf() to move it.
Array.prototype.move = function (old_index, new_index) {
if (new_index >= this.length) {
var k = new_index - this.length;
while ((k--) + 1) {
this.push(undefined);
}
}
this.splice(new_index, 0, this.splice(old_index, 1)[0]);
return this; // for testing purposes
};
var array = [0,0,0,0,3,0,0,0,0];
var result = array.move(array.indexOf(3),0);
console.log(result);
JSFiddle Demo

Why does console.log() keep on going in this loop?

I defined a variable 'i' to be equal to 2, and then say: if 'i' is between 0 and 2, let the function 'animate' run. However, if I open up the console in JSFiddle (option-command-I), the console.log() continues decreasing by 1 below 0! Am I using the conditional in the if statement improperly?
var interval = window.setInterval(animate, 500);
var i = 2;
if (0 < i < 2) {
function animate() {
alert('run');
i--;
console.log(i);
}
}
JSFiddle: http://jsfiddle.net/lpsternotes/RuLHn/
There are two problems here.
Firstly, there is this: 0<i<2. This will always evaluate to true.
Why? What you hoped it meant was "i is between 0 and 2" (which could be written as 0<i && i<2). But to a JS compiler, it is just two instances of the < operator. First, 0<i is evaluated, resulting in either true or false; then, that result is compared against <2 - so we have either true<2 or false<2. In order to answer that question, JS must "cast" the true or false to an integer. It treats false as 0, and true as 1; since these are both <2, the final result is always true.
Secondly, there is the position of your if statement, which is checked only once:
if (0 < i < 2) {
function animate() {
If you read through the code, you will see that there is no way of getting back to the line above this if statement, since the only repeating part of the code is the interval repeatedly running the animate function. To run each time the function runs, the if needs to be inside the function, not the other way around.
You need to clear interval once you satisfy the condition and move the if condition (note that 0 < i < 2 needs to be split into 2 conditions joined with && but here you can just do) with modification inside the function.
var interval = window.setInterval(animate, 500);
var i = 2;
function animate() {
if (i > 0) {
console.log('run');
i--;
console.log(i);
}
else{
window.clearInterval(interval);
}
}
Why don't you put if statement inside your animate function?
var i = 2;
function animate () {
if (i> 0 && i<2) {
alert('run');
i--;
console.log(i);
}
}
Edit:
1) you might want to use i>0 && i<2 rather than 0
2) Not sure if you do need to clear the interval after the condition is met. Would be better if you could elaborate a bit more about your requirements.

Trouble pushing to an array in JS

Below is just a section of my code but I know it's problematic because I can't get it to return any value except 'undefined'. I have been over this for hours and cannot figure it out.
I want to be able to input a number and have its factors pushed to an array. I have tested it by alerting the first item in the array and I get nothing. I'm sure this is a pretty easy but I just can't figure it out. Here is the code:
var numberInQuestion = prompt("Of what number are you wanting to find the largest prime factor?");
//determine factors and push to array for later use
var factorsArray = [];
function factors(numberInQuestion){
for(var i = 2; i < numberInQuestion-1; i++){
if(numberInQuestion % i === 0){
return factorsArray.push[i];
} else {
continue;
}
}
};
factors(numberInQuestion);
alert(factorsArray[0]);
Thanks for any help!
you can only return one value
you must use (), not [] for calling push
factorsArray should be local to factors (put the definition inside the function)
the else { continue; } is useless
Here is the fully corrected code:
var numberInQuestion = prompt("Of what number are you wanting to find the factors of?");
//determine factors
function factors(numberInQuestion){
var factorsArray = []; // make it local
for (var i = 2; i < numberInQuestion-1; i++){
if(numberInQuestion % i === 0){
factorsArray.push(i); // use (), and don't return here
} // no need for else { continue; } because it's a loop anyway
}
return factorsArray; // return at the end
};
var result = factors(numberInQuestion); // assign the result to a variable
alert(result);
Here's a JSFiddle.
You have an error in your pushing syntax. Correct syntax for pushing is -
factorsArray.push(i);
Also returning immediately from the function after finding the first divisor will not give you the full list. You probably want to return after you've found out all the divisors.
Taking all of the above into consideration, you should rewrite your function as follow -
function factors(numberInQuestion){
for(var i = 2; i < numberInQuestion - 1; i++){
if(numberInQuestion % i === 0) {
factorsArray.push(i);
}
}
}
and you will be OK.
You've coded this so that when you find the first factor your function returns immediately. Just get rid of the return keyword in that statement. (What "return" means in JavaScript and other similar languages is to immediately exit the function and resume from where the function was called.)
Oh, also, you call functions (like .push()) with parentheses, not square brackets.
The function should not return when pushing to the array. Return the array after executing the loop. The else clause is also unnecessary.
var numberInQuestion = prompt("Of what number are you wanting to find the largest prime factor?");
function factors(numberInQuestion){
var factorsArray = [];
for(var i = 2; i < numberInQuestion-1; i++){
if(numberInQuestion % i === 0 && isPrime(i)){
factorsArray.push(i);
}
}
return factorsArray;
};
var factors = factors(numberInQuestion);
alert(factors[factors.length-1]);
//From: http://stackoverflow.com/questions/11966520/how-to-find-prime-numbers
function isPrime (n)
{
if (n < 2) return false;
var q = Math.sqrt (n);
for (var i = 2; i <= q; i++)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
Given the purpose of the example two items must be considered
The code does not determine if the number is actually prime. The code will return the smallest factor possible since the loop starts at two and increments, then returns the first element in the array. The largest factor would actually be the last element in the array. I have corrected the example to find the greatest prime factor. You can test it via this fiddle: http://jsfiddle.net/whKGB/1/

Categories

Resources