Absence and presence of curly brace in "if" statement - javascript

var i = 0,
j = 8;
checkiandj: while (i < 4) {
console.log("i: " + i);
i += 1; // i=1;
checkj: while (j > 4) { //j=8
console.log("j: "+ j);
j -= 1; // 7
if ((j % 2) == 0)
continue checkj;
console.log(j + " is odd.");
}
console.log("i = " + i);
console.log("j = " + j);
}
How does this part of the code works?
if ((j % 2) == 0)
continue checkj;
console.log(j + " is odd.");
Is it like this?
if ((j % 2) == 0)
continue checkj;
else
console.log(j + " is odd.");
or like this?
if ((j % 2) == 0) {
continue checkj;
}
console.log(j + " is odd.");
And if I will read this statement(original one) at first look, I will understand it as: if Divide modulo 2 equal zero , do both continue checkj and console.log, not only continue. I know that what makes "continue" , but it`s hard to understand this action without curly braces. How can I understand better absence of curly braces?

Related

why is outer variable not available in if conditional

function NumStuff(num) {
this.num = num;
this.multipleOfFour = function() {
//if multiple of 4
if (this.num % 4 === 0) {
console.log(this.num + " is a multiple of Four");
console.log("the structure of the given integer " +
this.num + " is ");
for (let i = 0; i < this.num; i++) {
if (4 * i === this.num) { //why is this.num outside of
//lexical scope
console.log(this.num + " = " + i + " x 4");
break;
}
}
//if not a multiple of 4
} else {
console.log(this.num + " isn't a multiple of 4 but here is the integer's structure:");
let remainder = this.num % 4;
let tempNum = this.num - remainder;
for (let i = 0; i < tempNum; i++) {
if (4 * i === tempNum) {
console.log(this.num + " = " + i + " x 4 + " + remainder);
break;
}
}
}
};
}
let num = prompt("Enter an integer:");
let n = new NumStuff(num);
n.multipleOfFour();
Say we enter 20 as our num. It passes through the multipleOfFour() and hits the first if conditional. This.num(20) % 4 is equal to 0 so it passes.Then we loop through i to find what number times 4 is equal to 20. This.num is in the scope of the for statement but not in the scope of the inner if conditional of the for statement. Why is that so?
It is in the scope. That's not the issue.
But this.num is a string (that's what prompt always returns) while 4 * i is a number. And 4 * i === this.num will always be false, regardless of what you enter when prompted.
Try this (here):
for (let i = 0; i < this.num; i++) {
console.log('x', 4 * i, this.num, 4 * i === this.num);
An easy fix is let num = parseInt(prompt("Enter an integer:"));.

checkPrime function returns incorrect values

numbers = [];
for (x = 1; x <= 1e4; x++) {
numbers.push(x)
}
//console.log(numbers)
function checkPrime(num) {
if (num == 1 || num == 0) {
return 'It is a separate case'
}
if (num == 2) {
return num + ' is prime'
}
for (var i = 2; i < num; i++) {
if (num in numbers) {
if (num % i === 0) return num + ' is not prime';
else {
return num + ' is prime';
}
return num !== 1;
} else {
return num + ' is not in range';
}
}
}
console.log(checkPrime(27));
Hi.
In the above code, I tried to create a function which returns information about whether a number is prime or not.
However, it fails in some cases. Like eg. in the case of 27 or 145, it returns the values are prime, which obviously is false. How can I amend this program to make it work?
Also, what is the smartest way of merging the case for number 2 and the rest prime numbers?
Thanks in advance and sorry if this is too basic, I could not find the right answer anywhere else.
You are putting the 'else' clause that states the number is prime before having finished to check all numbers until itself -1.
To be optimal, you don't need to loop until the number ( < num). Just until the square root of the number. (even better than looping until num/2) For example : 167 can be seen that is prime when the loop has reached 13. 13*13 = 169 > 167 so you can stop and safely afirm that 167 is prime.
For number 2 it is correct to have a sepparate case.
Below is the code for checking a single value if it is prime:
function checkPrime(num) {
if (num == 1 || num === 0) {
return 'It is a separate case'
}
if (num == 2) {
return num + ' is prime'
}
for (var i = 2; i < Math.sqrt(num); i++) {
if (num % i === 0) return num + ' is not prime';
}
return num + ' is prime';
}
alert(checkPrime(27));
I have rewritten the code to provide the right answer
numbers = [];
for (x = 1; x <= 1e4; x++) {
numbers.push(x)
}
//console.log(numbers)
function checkPrime(num) {
if (num == 1 || num == 0) {
return 'It is a separate case'
}
// check this condition outside the loop
if (!(num in numbers)) {
return num + ' is not in range';
}
if (num == 2) {
return num + ' is prime'
}
for (var i = 2; i < num; i++) {
if (num % i === 0) {
return num + ' is not prime';
}
}
return num + ' is prime';
}
console.log(checkPrime(27));
I've rewritten your code and made a couple of changes.
The reason you were having your problem is that you were returning in the for loop meaning all odd numbers would declare themselves as prime numbers.
I've fixed this but also I've I rearranged things a little, to be as efficient as possible it's good to bail as soon as possible so I do a couple of checks to bail initially I check if the number is in range, if not bail.
I've commented the code so it makes sense but if you don't understand why I've done something feel free to ask.
// make an array of all numbers between 0 and 10000
numbers = [];
for (x = 0; x <= 1e4; x++) {
numbers.push(x)
}
function checkPrime(num) {
// return if input number is not in numbers array
if (numbers.indexOf(num) == -1) return num + ' is not in range'
// return if number is 0 or 1
if (num <= 1) return 'It is a separate case'
// check all numbers between 2 and input number
// return if any number devides neatly
for (var i = 2; i < num; i++)
if (num % i === 0) return num + ' is not prime';
// if you get this far it's prime
return num + ' is prime';
}
console.log(checkPrime(27));
Personally, for the range, I wouldn't have an array of all the values but I've left this in just in case there was some other reasoning we don't know about.
EDIT:
As you've said the initial array is not important I've remade the code to work without it, I've not included comments this time (to save space) but that code does the same thing and is mostly unchanged.
function checkPrime(num) {
if (num < 0 || num > 1e4) return num + ' is not in range'
if (num <= 1) return 'It is a separate case'
for (var i = 2; i < num; i++)
if (num % i === 0) return num + ' is not prime';
return num + ' is prime';
}
console.log(checkPrime(27));
Anyway, I hope you find this helpful 🙂

Changing for loop to while loop crashes javascript webpage?

New to JS. I'm trying to change my for loop to a while loop. It prints the factors of a number, but for some reason, the while loops causes the webpage to stop responding. Any help is appreciated.
var num, i = 1,
array = [];
num = parseInt(prompt("Please enter a number:"));
while (i < num) {
if (num % i == 0) {
array.push(i);
i++;
}
}
alert("The factors of " + num + " are: " + array + " and " + num);
Move the incrementation of i variable outside the if condition. Else - the while loop will be stuck when the num is not divisible by specified i.
For example - if num is 5 and i is 2, the loop will be stuck because the if condition is not fulfilled - that's why i won't be incremented - and then we will experience an infinite loop.
var num, i = 1, array = [];
num = parseInt(prompt("Please enter a number:"));
while (i < num) {
if (num % i == 0) {
array.push(i);
}
i++;
}
alert("The factors of " + num + " are: " + array + " and " + num);
You increment i only if the condition of the "if" block is true. If that condition evaluates to false, i can't be incremented, and therefore the loop never ends.
if (num % i == 0) { // <some value except 0> % 1 == 0 -> false
array.push(i);
i++;
}
so try:
while (i < num) {
if (num % i == 0) {
array.push(i);
}
i++; // now i can be incremented regardless of the condition in the "if" block.
}

Values concatenating inside if condition

Edit: For the sake of simplicity, consider following code:
var z = {x: 1, y: 1};
console.log(z.x+5 + ' ' + z.y+5);
Why output is (6,15) instead of (6,6)?
Before edit: I have following function:
function findPath(startX, startY, goalX, goalY){
var queue = [],
candidates = [],
path = [];
queue.push({x: startX, y: startY, searchDistance: 0, hasBeenSearched: true});
fillQueue();
function fillQueue(){
setInnerHTML(queue[0].x, queue[0].y, '.');
for(var i=-1; i<=1; i++){
if(queue[0].x + i < 0 || queue[0].x + i > boardHeight - 1){
continue;
}
for(var j=-1; j<=1; j++){
if(queue[0].y + j < 0 || queue[0].y + j > boardWidth - 1){
continue;
}
if(i == 0 && j == 0){
continue;
}
if(cells[queue[0].x + i][queue[0].y + j].type.blockMovement == true || findCell(queue[0].x + i, queue[0].y + j).hasBeenSearched == true){
console.log(queue[0].x + i + ' ' + queue[0].y + j)
continue;
}
if((queue[0].x + i == goalX) && (queue[0].y + j == goalY)){
setInnerHTML(queue[0].x + i, queue[0].y + j, '.');
candidates.push(queue[0]);
candidates.push({x: queue[0].x + i, y: queue[0].y + j, searchDistance: queue[0].searchDistance + 1, hasBeenSearched: true});
//fillPath();
return path;
}
queue.push({x: queue[0].x + i, y: queue[0].y + j, searchDistance: queue[0].searchDistance + 1, hasBeenSearched: true});
}
}
candidates.push(queue.shift());
if(queue.length > 0){
setTimeout(fillQueue, 0);
}else{
return 'no path found';
}
function findCell(x,y){
for(var i=0; i<queue.length; i++){
if(queue[i].x == x && queue[i].y == y){
return queue[i];
}else if(i == queue.length - 1 && (queue[i].x != x || queue[i].y != y)){
return {hasBeenSearched: false};
}
}
}
}
}
It is part of pathfinding algorithm I've been rewriting lately and I have following problem. Inside inner for loop, when this condition findCell(queue[0].x + i, queue[0].y + j).hasBeenSearched == true is being checked, values of second parameter queue[0].y and j are concatenated instead of just being added, while same condition for first parameter works correctly (values there are added). I'm trying to figure that out for several hours now and I have no idea what is going on. Both values queue[0].y and j are numbers(I checked it by console logging typeof them), and should be added just like similiar values in first paremeter. Any help with pointing me out what I did wrong will be appreciated. Thank you in advance.
Codepen link: http://codepen.io/Furmanus/pen/LkXVwO/?editors=0011
JS expressions are evaluated left-to-right. By the time it reaches that last +, it's evaluating ('6 1' + 5).
Put the last part in parentheses to force it to be evaluated separately: console.log(z.x+5 + ' ' + (z.y+5)).
You can also log multiple things using parentheses, which will avoid this problem: console.log(z.x+5, z.y+5).
Actually, the arguments of the findCell() function are always Numbers.
The only place where there is a string is:
console.log(queue[0].x + i + ' ' + queue[0].y + j)
This prints a string because sum is calculated from left to right.
Let's do it step by step:
queue[0].x + i are two numbers, and they are summed, and they oroduces a number (let's call it xi
So now our operation is:
console.log(xi + ' ' + queue[0].y + j)
xi is a Number, and it is summed to ' ' which is a string. They produce a string (this is how JS does casting)
From here on, you sum strings and numbers, so first of all queue[0].y is casted to string and it is concatenated, then j is casted to string too and concatenated in the same way.
Solution is to force the precedence of operators:
console.log(queue[0].x + i + ' ' + (queue[0].y + j))
TL;DR: the code is good, just the console.log is broken
When you concatenate the two values, the second one is converted to a string.
Instead, use:
var z = {x: 1, y: 1};
console.log(z.x+5 + ' ' + parseInt(z.y+5));
jsfiddle

Writing a program to find out the sum of the negative elements and positive elements of the array

My code runs well up until the point it is expected to return the result - it does not add up any of the values entered by the user.
a = (prompt("a:"));
b = (prompt("b:"));
c = (prompt("c:"));
negativeSum = Number(0);
positiveSum = Number(0);
var test = [a, b, c];
for (i = 0; i < test.length; i++) {
if (isNaN(test[i])) {
alert(test[i] + " : incorrect input.");
}
else
if (test[i] < 0) {
alert(test[i] + " : positive.")
negativeSum = Number(test[i]++);
}
else {
alert(test[i] + " : positive.")
positiveSum = Number(test[i]++);
}
}
alert(positiveSum + " : sum of +ve elements");
alert(negativeSum + " : sum of -ve elements");
isn't sum of negatives always less then sum of positives.
if you speaking about absolute diff.
than try
if (test[i] < 0) {
alert(test[i] + " : positive.")
negativeSum += Number(test[i]);
}
else {
alert(test[i] + " : positive.")
positiveSum += Number(test[i]);
}
//after the loop
return Math.abs(negativeSum) > positiveSum;
Several things - no need for Number(0) - just using 0 will do.
The line:
positiveSum = Number(test[i]++);
Simply assigns the value of test[i] + 1 (this is what the post increment ++ operator does) to positiveSum. It doesn't add it up to positiveSum (same is true for negativeSum.
This should work better:
negativeSum = 0;
positiveSum = 0;
var test = [a, b, c];
for (i = 0; i < test.length; i++) {
if (isNaN(test[i])) {
alert(test[i] + " : incorrect input.");
}
else
if (test[i] < 0) {
alert(test[i] + " : positive.")
negativeSum += test[i];
}
else {
alert(test[i] + " : positive.")
positiveSum += test[i];
}
}
In my code the line:
negativeSum += test[i];
Is equivalent to:
negativeSum = negativeSum + test[i];
You're not summing anything, you're incrementing each number you've input. You want positiveSum += (each number).
You should also convert the element to a number before doing the comparison to zero and the rest.

Categories

Resources