Since I am still fairly new to js I thought it couldn't hurt to ask more experienced coders about ways to improve my coding habits and to learn efficient basics.
So im wondering if I could run, say 2 lines of code in a loop x amount of times and then x amount of times on the rest of the block.
So instead of this:
for (let i = 0; i <= 10; i++) {
this.shapes[i].x -= 1;
this.shapes[i].draw(this.ctx);
}
for (let i = 0; i <= 10; i++) {
this.shapes[i].x += 1;
this.shapes[i].draw(this.ctx);
}
Does something like this exist?
for (let i = 0; i <= 10; i++) {
//run this section i amount of times
this.shapes[i].x -= 1;
this.shapes[i].draw(this.ctx);
//then run this i amount of times
this.shapes[i].x += 1;
this.shapes[i].draw(this.ctx);
}
The only difference between the two loops' bodies seems to be one statement.
You can use some math to determine the index and some logical statements to determine if that value should be incremented or decremented, here is an example:
for (let i = 0; i <= 21; i++) {
const index = i % 11;
this.shapes[index].x += (i > 10) ? 1 : -1;
this.shapes[index].draw(this.ctx);
}
If it's exactly the same code you can refactor it like this:
for (let delta of [-1, +1]) {
for (let i = 0; i <= 10; i++) {
this.shapes[i].x += delta;
this.shapes[i].draw(this.ctx);
}
}
Another option is to use a function using delta as a parameter
changeShapeByDelta = (delta) => {
for (let i = 0; i <= 10; i++) {
this.shapes[i].x += delta;
this.shapes[i].draw(this.ctx);
}
}
changeShapeByDelta(-1);
changeShapeByDelta(+1);
Another option is to deep copy your initial shapes and restore it after the first draw.
You could ofc. define more variables then i:
for (let i = 0, j=0; i <= 10; i++, j+= 2) {
console.log(i, j);
}
Or use another var in the parent scope:
let j = 0;
for (let i = 0, j=0; i <= 10; i++, j+= 2) {
j += 2
console.log(i, j);
}
Or just use plain old if,else and break statements. Code does not have to look nice all the time.
You can loop 20 times instead of 10 times and then run first code if i<10 else run second. Below is example with simple logging.
for(let i = 0;i<22;i++){
if(i<11) console.log('first')
else console.log('second')
}
Related
I'm learning JavaScript at the moment and have an exercise to solve. The exercise is given bellow:
Output prime numbers
An integer number greater than 1 is called a prime. if it cannot be divided without a
remainder by anything except 1 and itself.
In other words, n > 1 is a prime if it can’t be evenly divided by anything except 1 and n .
For example, 5 is a prime, because it cannot be divided without a remainder by 2 , 3 and 4 .
Write the code which outputs prime numbers in the interval from 2 to n .
For n = 10 the result will be 2,3,5,7 .
P.S. The code should work for any n , not be hard-tuned for any fixed value.
Now i try to solve it this way.
let n = 20;
outer:
for (let i = 2; i < n; i++) {
for (let j = 1; j < n; j++) {
while (j>1 && j<i) {
if (i%j == 0 ) {
continue outer
}
}
}
console.log(i);
}
but it show wrong output
now i also can solve it in this way
let n = 20;
let result = 0;
outer:
for (let i = 2; i < n; i++) {
for (let j = 2; j < i; j++) {
if (i%j == 0) {
continue outer
}
}
console.log(i)
}
Now I ask for your help to know that exactly in where I did mistake in 1st Salutation .
The problem is that if if (i%j == 0 ) is false you remain in the while without changing the variables so you are infinite stuck there.
You could add another label for the inner for and either go to the one or the other
let n = 20;
outer: for (let i = 2; i < n; i++) {
inner: for (let j = 1; j < n; j++) {
while (j>1 && j<i) {
if (i%j == 0 ) {
continue outer;
} else {
continue inner;
}
}
}
console.log(i);
}
for(var i = 0; i <= 10; i+1){
console.log(i); // the loop goes on and on
}
why this for loop don't stop ? I did specifically typed in condition that it need to stop on 10.
The i+1 is your issue. It should be i = i + 1, i++ or i+=1
These are just different ways of adding 1 to the current value of i
for(var i = 0; i <= 10; i++){
console.log(i);
}
You never change i.
for (var i = 0; i <= 10; i + 1) {
^^^^^
You need to increment i
for (var i = 0; i <= 10; i++) { // or
for (var i = 0; i <= 10; i = i + 1) {
It's missing the =: i is not being mutated:
for(var i = 0; i <= 10; i += 1){
console.log(i); // the loop goes on and on
}
Change it to i++ and it will work. Right now you are just checking against 0+1 every loop iteration, and that will never be > 10.
I'm trying to make a loop where one value goes up while the second goes down.. I cant figure it out. As far as I can see checkNumber counts down correctly, and x and i are incorrect
I know i'm making a silly mistake somewhere but I'm brand new to coding
var checkNumber = 5;
for (var x = 0; x < 5; x++) {
for (var i = 0; i < checkNumber; i++) {
console.log(checkNumber);
checkNumber = checkNumber - 1;
console.log("x",x,"i",i);
}
}
Just use a single loop and take the difference of the max value and the actual value (minus one, because of the zero based nature) for the second value.
var value = 5,
i;
for (i = 0; i < value; i++) {
console.log(i, value - i - 1);
}
I'm assuming you're trying to do this:
var checkNumber = 5;
for (var x = 0; x < checkNumber; x++) {
for (var i = checkNumber - 1; i >= 0; i--) {
console.log(checkNumber);
console.log("x", x, "i", i);
}
}
This will start i at 4 (minus one to avoid index issues if that's what you're looking for, otherwise remove the -1) and go down to 0.
The first loop will count up until 4.
The trick is to use i-- and set i to something higher, then stop the loop with the second condition in the for.
Does that make sense?
This will make i start at 0 and j start at 4. While i goes up to 4, j will go down to 0.
var checkNumber = 5;
for(var i = 0, j = checkNumber - 1; i < checkNumber; i++, j--){
console.log(i + " " + j);
}
So, I'm new to javascript, and - after completing the JS unit on codecademy, I'm working through Project Euler to get a better feel for the language. The problem is that I'm stuck on the second challenge. I feel pretty dumb at this point. The problem is to find the sum of all the even fibonacci numbers that are less than four million.
var fib = [1,2];
var stack = [];
for (i = 2; i < 4000000; i++) {
fib[i] = fib[i - 1] + fib[i - 2];
}
That part works. I'm using JSFiddle, and it will print out the fibonacci sequence up to four million. The problem is the next part:
for (j = 0; j < fib.length; j++) {
if (fib[i] % 2 === 0) {
stack[j] = fib[i];
}
}
I've tried that bit both inside and outside the for loop, and I can't figure this out. I have this feeling that I'm missing something obvious. Any help would be appreciated. Thanks :D
EDIT: I figured it out. Thank all of you! Here's what I did:
var total = 0;
var fib = [1, 2];
//In my first attempt, I made a set of the first 4,000,000
//fibonacci numbers. I just left the "4000000" there
//arbitrarily.
for (i = 2; i < 4000000; i++) {
//This makes sure that I don't go over 4000000 in the array.
if (fib[i - 1] < 4000000) {
fib[i] = fib[i - 1] + fib[i - 2];
}
}
for (j = 0; j < fib.length; j++) {
if (fib[j] % 2 === 0) {
total += fib[j];
}
}
alert(total);
And it printed out the correct answer! Woot.
Replace this
for (j = 0; j < fib.length; j++) {
if (fib[i] % 2 === 0) {
stack[j] = fib[i];
}
}
with this
for (j = 0; j < fib.length; j++) {
if (fib[j] % 2 === 0) {
stack[j] = fib[i];
}
}
And also, the problem says to only find fibonacci numbers below 4_000_000. There is no need to create 4 million fibonacci numbers. That would take forever. Try something smaller like 70.
I see a couple of issues with this.
You say that you want to find the sum of all even fibonacci numbers? I don't get the point of putting the even results into another array and then dealing with them. Try something like this:
var fib = [1,2];
var result = 0;
for (i = 2; i < 4000000; i++) {
fib[i] = fib[i - 1] + fib[i - 2];
}
for (j = 0; j < fib.length; j++) {
if(fib[j] % 2 == 0){
result = result + fib[j];
}
}
Secondly, you phrase it as "all even fibonacci numbers less than 4 million". Are you sure that they want the first 4 million fibonacci numbers, or the fibonacci numbers that are under 4 million?
This question already has answers here:
What's the best way to break from nested loops in JavaScript? [closed]
(18 answers)
Closed 3 years ago.
I tried this:
for(i = 0; i < 5; i++){
for(j = i + 1; j < 5; j++){
break(2);
}
alert(1);
}
only to get:
SyntaxError: missing ; before statement
So, how would I break a nested loop in JavaScript?
You should be able to break to a label, like so:
function foo () {
dance:
for (var k = 0; k < 4; k++) {
for (var m = 0; m < 4; m++) {
if (m == 2) {
break dance;
}
}
}
}
You need to name your outer loop and break that loop, rather than your inner loop - like this.
outer_loop:
for(i=0;i<5;i++) {
for(j=i+1;j<5;j++) {
break outer_loop;
}
alert(1);
}
There are at least five different ways to break out of two or more loops:
1) Set parent(s) loop to the end
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
{
i = 5;
break;
}
}
}
2) Use label
fast:
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
break fast;
}
}
3) Use variable
var exit_loops = false;
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
{
exit_loops = true;
break;
}
}
if (exit_loops)
break;
}
4) Use self executing function
(function()
{
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
return;
}
}
})();
5) Use regular function
function nested_loops()
{
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
return;
}
}
}
nested_loops();
See Aaron's. Otherwise:
j=5;i=5 instead of break.
loop1:
for (var i in set1) {
loop2:
for (var j in set2) {
loop3:
for (var k in set3) {
break loop2; // breaks out of loop3 and loop2
}
}
}
code copied from Best way to break from nested loops in Javascript?
Please search before posting a question. The link was the FIRST related question I saw on the left side of this page!
Unfortunately you'll have to set a flag or use labels (think old school goto statements)
var breakout = false;
for(i=0;i<5;i++)
{
for(j=i+1;j<5;j++)
{
breakout = true;
break;
}
if (breakout) break;
alert(1)
};
The label approach looks like:
end_loops:
for(i=0;i<5;i++)
{
for(j=i+1;j<5;j++)
{
break end_loops;
}
alert(1)
};
edit: label incorrectly placed.
also see:
http://www.devguru.com/Technologies/ecmascript/quickref/break.html
http://www.daaq.net/old/javascript/index.php?page=js+exiting+loops&parent=js+statements
In my opinion, it's important to keep your construct vocabulary to a minimum. If I can do away with breaks and continues easily, I do so.
function foo ()
{
var found = false;
for(var k = 0; (k < 4 && !found); k++){
for(var m = 0; (m < 4 && !found); m++){
if( m === 2){
found = true;
}
}
}
return found;
}
Be warned, after the loop, m and k are one larger that you might think. This is because m++ and k++ are executed before their loop conditions. However, it's still better than 'dirty' breaks.
EDIT: long comment #Dennis...
I wasn't being 100% serious about being 'dirty', but I still think that 'break' contravenes my own conception of clean code. The thought of having multi-level breaks actually makes me feel like taking a shower.
I find justifying what I mean about a feeling about code because I have coded all life. The best why I can think of it is is a combination of manners and grammar. Breaks just aren't polite. Multi level breaks are just plain rude.
When looking at a for statement, a reader knows exactly where to look. Everything you need to know about the rules of engagement are in the contract, in between the parenthesis. As a reader, breaks insult me, it feels like I've been cheated upon.
Clarity is much more respectful than cheating.
Use function for multilevel loops - this is good way:
function find_dup () {
for (;;) {
for(;;) {
if (done) return;
}
}
}
Wrap in a self executing function and return
(function(){
for(i=0;i<5;i++){
for (j=0;j<3;j++){
//console.log(i+' '+j);
if (j == 2) return;
}
}
})()
You return to "break" you nested for loop.
function foo ()
{
//dance:
for(var k = 0; k < 4; k++){
for(var m = 0; m < 4; m++){
if(m == 2){
//break dance;
return;
}
}
}
}
foo();
break doesn't take parameters. There are two workarounds:
Wrap them in a function and call return
Set a flag in the inner loop and break again right after the loop if the flag is set.
Break 1st loop:
for(i=0;i<5;i++)
{
for(j=i+1;j<5;j++)
{
//do something
break;
}
alert(1);
};
Break both loops:
for(i=0;i<5;i++)
{
var breakagain = false;
for(j=i+1;j<5;j++)
{
//do something
breakagain = true;
break;
}
alert(1);
if(breakagain)
break;
};
You can break nested for loops with the word 'break', it works without any labels.
In your case you need to have a condition which is sufficient to break a loop.
Here's an example:
var arr = [[1,3], [5,6], [9,10]];
for (var a = 0; a<arr.length; a++ ){
for (var i=0; i<arr[a].length; i++) {
console.log('I am a nested loop and i = ' + i);
if (i==0) { break; }
}
console.log('first loop continues');
}
It logs the following:
> I am a nested loop and i = 0
> first loop continues
> I am a nested loop and i = 0
> first loop continues
> I am a nested loop and i = 0
> first loop continues
The return; statement does not work in this case.
Working pen
function myFunction(){
for(var i = 0;i < n;i++){
for(var m = 0;m < n;m++){
if(/*break condition*/){
goto out;
}
}
}
out:
//your out of the loop;
}