Can a for loop increment/decrement by more than one? - javascript

Are there other ways to increment a for loop in Javascript besides i++ and ++i? For example, I want to increment by 3 instead of one.
for (var i = 0; i < myVar.length; i+3) {
//every three
}

Use the += assignment operator:
for (var i = 0; i < myVar.length; i += 3) {
Technically, you can place any expression you'd like in the final expression of the for loop, but it is typically used to update the counter variable.
For more information about each step of the for loop, check out the MDN article.

A for loop:
for(INIT; TEST; ADVANCE) {
BODY
}
Means the following:
INIT;
while (true) {
if (!TEST)
break;
BODY;
ADVANCE;
}
You can write almost any expression for INIT, TEST, ADVANCE, and BODY.
Do note that the ++ operators and variants are operators with side-effects (one should try to avoid them if you are not using them like i+=1 and the like):
++i means i+=1; return i
i++ means oldI=i; i+=1; return oldI
Example:
> i=0
> [i++, i, ++i, i, i--, i, --i, i]
[0, 1, 2, 2, 2, 1, 0, 0]

for (var i = 0; i < 10; i = i + 2) {
// code here
}​

Andrew Whitaker's answer is true, but you can use any expression for any part.
Just remember the second (middle) expression should evaluate so it can be compared to a boolean true or false.
When I use a for loop, I think of it as
for (var i = 0; i < 10; ++i) {
/* expression */
}
as being
var i = 0;
while( i < 10 ) {
/* expression */
++i;
}

for (var i = 0; i < myVar.length; i+=3) {
//every three
}
additional
Operator Example Same As
++ X ++ x = x + 1
-- X -- x = x - 1
+= x += y x = x + y
-= x -= y x = x - y
*= x *= y x = x * y
/= x /= y x = x / y
%= x %= y x = x % y

You certainly can. Others have pointed out correctly that you need to do i += 3. You can't do what you have posted because all you are doing here is adding i + 3 but never assigning the result back to i. i++ is just a shorthand for i = i + 1, similarly i +=3 is a shorthand for i = i + 3.

For those who are looking to increment pair of numbers (like 1-2 to 3-4):
Solution one:
//initial values
var n_left = 1;
var n_right = 2;
for (i = 1; i <= 5; i++) {
console.log(n_left + "-" + n_right);
n_left =+ n_left+2;
n_right =+ n_right+2;
}
//result: 1-2 3-4 5-6 7-8 9-10
Solution two:
for (x = 0; x <= 9; x+=2) {
console.log((x+1) + "-" + (x+2));
}
//result: 1-2 3-4 5-6 7-8 9-10

The last part of the ternary operator allows you to specify the increment step size. For instance, i++ means increment by 1. i+=2 is same as i=i+2,... etc.
Example:
let val= [];
for (let i = 0; i < 9; i+=2) {
val = val + i+",";
}
console.log(val);
Expected results: "2,4,6,8"
'i' can be any floating point or whole number depending on the desired step size.

There is an operator just for this. For example, if I wanted to change a variable i by 3 then:
var someValue = 9;
var Increment = 3;
for(var i=0;i<someValue;i+=Increment){
//do whatever
}
to decrease, you use -=
var someValue = 3;
var Increment = 3;
for(var i=9;i>someValue;i+=Increment){
//do whatever
}

Related

How to concatonate string in iteration loop [duplicate]

This question already has answers here:
Concatenate string through for loop
(4 answers)
Closed 3 years ago.
My output is
1
1
2
1
2
3
…
The output I am looking for is
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
var x,y;
for(x=1; x <= 5; x++){
for (y=1; y <= x; y++) {
console.log(y)
}
}
You could take a single loop with a part variable and one for the full string.
Then you need to add a space only if the string is not empty and add in each loop the new value and the actual part to the full string.
var i,
part = '',
full = '';
for (i = 1; i <= 5; i++) {
part += (part && ' ') + i;
full += (full && ' ') + part;
}
console.log(full);
Try with this code:
var x,y,z='';
for(x=1; x <= 5; x++){
for (y=1; y <= x; y++) {
z = z + y + ' ';
}
}
console.log(z);
Try the snippet below:
var str = ''
for (let i = 1; i <= 5; i++) {
for (let j = 1; j <= i; j++) {
str += `${j} `
}
}
console.log(str)
This should work for you:
var x, y, concatenatedString = '';
for(x = 1; x <= 5; x++) {
for (y=1; y <= x; y++) {
concatenatedString += `${y} `
}
}
console.log(concatenatedString)
You are console logging each time which puts it on a new line.
It's a better idea to store numbers in an array and then print out one by one.
var x, y, myArray[];
for (x = 1; x <= 5; x++) {
for (y = 1; y <= x; y++) {
myString += y.toString() + " ";
}
}
console.log(myString);
You could also place numbers in an array and output one by one.

looping an array within an array

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);
}

Need help to fix a snippet from my math grid maze solver

The idea behind the following code is to test if any number between 0 and 13 + any other number equals 13. If one does both numbers should be saved to a different array but on the same index. So i should have all possible combinations to reach 13 in 2 arrays. But when i run my code I only get 2 combinations which are 0+13 and 13+0. Here is the code:
var number1 = [];
var number2 = [];
var index = 0;
var i = 0;
var j = 0;
//Tests if i + j (from the loop) add up to 13
var test = function(i, j) {
if (i + j === 13) {
number1[index] = i;
number2[index] = j;
index =+ 1;
}
}
//1st loop generates i from 0 to 13 in 0.5 step.
for (i = 0; i < 13.5; i += 0.5) {
//same for j, this number should test with i every loop
for (j = 0; j < 13.5; j += 0.5) {
test(i, j);
}
}
//outputs the 2 arrays, the matching numbers should be stored in
for (i = 0; i < number1.length; i++) {
console.log(number1[i]);
console.log(number2[i]);
}
Change index =+ 1 to index += 1
Then index =+ 1 sets the index to 1 it does not increment it by 1 (as you want)
See Expressions and operators: Assignment operators MDN

Generating alphanumerical sequence javascript

I have written a terribly slow function for generating codes that go from AA000 to ZZ999 (in sequence not random). And I have concluded that there has to be a better way to do this. Any suggestions on how to make this faster?
function generateAlphaNumeric(){
theAlphabet = ['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'];
resultArrray = [];
resultArrray2 = [];
teller = 0;
for(i in theAlphabet){
for(x in theAlphabet){
resultArrray[teller] = theAlphabet[i] + theAlphabet[x];
teller++;
}
}
teller = 0;
for(x = 0; x<10; x++){
for(y = 0; y<10; y++){
for(z = 0; z<10; z++){
resultArrray2[teller] = x.toString() + y.toString() +z.toString();
teller++;
}
}
}
teller = 0;
finalArray = [];
for(index in resultArrray){
for(i in resultArrray2){
finalArray[teller] = resultArrray[index] + resultArrray2[i];
teller++;
}
}
//console.log(resultArrray);
//console.log(resultArrray2);
console.log(finalArray);
}
This should be considerably faster:
var theAlphabet = ['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 theDigits = ['0','1','2','3','4','5','6','7','8','9'];
var result = [];
for (var i=0 ; i<26 ; i++) {
var prefix1 = theAlphabet[i];
for (var j=0 ; j<26; j++) {
var prefix2 = prefix1 + theAlphabet[j];
for(var x = 0; x<10; x++){
var prefix3 = prefix2 + theDigits[x];
for(var y = 0; y<10; y++){
var prefix4 = prefix3 + theDigits[y];
for(var z = 0; z<10; z++){
result.push(prefix4 + theDigits[z]);
}
}
}
}
}
Key ideas:
Generate everything in one run
Reuse partial strings as much as possible
However, I don't see how such an exhaustive list is useful. There are exactly 26 * 26 * 1000 different codes. So instead of maintaining an array with all codes it could make sense to simply build a function that generates the specific code requested:
function getCode(number) {
var z = number % 10;
number -= z; number /= 10;
var y = number % 10;
number -= y; number /= 10;
var x = number % 10;
number -= x; number /= 10;
var a = number % 26;
number -= a; number /= 26;
var b = number;
return theAlphabet[a] + theAlphabet[b] + theDigits[x] + theDigits[y] + theDigits[z];
}
function generate() {
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
array = [];
for (var i = 0; i < str.length; i++) {
for (var j = 0; j < str.length; j++) {
for (var k = 0; k < 10; k++) {
for (var l = 0; l < 10; l++) {
for (var m = 0; m < 10; m++) {
ar.push(str[i] + str[j] + k + l + m);
}
}
}
}
}
return array;
}
console.log(generate());
This will generate a array of all the codes .. U can save that array and parse it easily using a loop.
Try this solution:
function generate() {
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
ar = [];
for (var index1 = 0; index1 < str.length; index1++) {
for (var index2 = 0; index2 < str.length; index2++) {
for (var index3 = 0; index3 < 1000; index3++) {
ar.push(str[index1] + str[index2] + ('000' + index3).slice(-3));
}
}
}
return ar;
}
console.log(generate());
I didn't test it, but it should do the trick
function generateAlphaNumeric()
{
var theAlphabet = ['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 result = [];
// Will take a random letter inside theAlphabet
// Math.floor(Math.random() * theAlphabet.length) will generate a random number between 0 and 25
var i = 0;
while(i<2)
{
var letter = theAlphabet[Math.floor(Math.random() * theAlphabet.length)];
result.push(letter);
i++;
}
i = 0;
while(i<3)
{
// Adds a random number between 0 and 9
result.push(Math.floor(Math.random() * 10));
i++;
}
return result;
}
From a computational complexity perspective, unfortunately this is the best you can do. From a sheer number of instructions perspective, you can do a bit better (as others have pointed out), but it's still going to be the same order of complexity (remember that constants / multipliers are irrelevant in big-O complexity). You can also optimize the storage a bit.
Think about it. Your array needs to have 26 * 26 * 10 * 10 * 10 members. This means you need to at least touch that many elements.
Let N = number of elements in the alphabet
Let M = number of elements in your digit queue
Best Case Order Complexity = O(N * N * M * M * M) (if all you had to do was assign values)
Best case storage complexity = same as above (you have to store all the codes)
Right now you are using the following operations:
for(i in theAlphabet){ // *O(N)*
for(x in theAlphabet){ // *O(N)*
resultArrray[teller] = theAlphabet[i] + theAlphabet[x];// *(O(1))*
}
}
for(x = 0; x<10; x++){ // O(M)
for(y = 0; y<10; y++){ // O(M)
for(z = 0; z<10; z++){ // O(M)
resultArrray2[teller] = x.toString() + y.toString() +z.toString(); // O(1) (technically this is O(length of x + y + z)
teller++;
}
}
}
for(index in resultArrray){ // O(N * N)
for(i in resultArrray2){ // O(M * M * M(
finalArray[teller] = resultArrray[index] + resultArrray2[i]; //O(1)
teller++;
}
}
So at the end of the day your order complexity is O(N * N * M * M * M), which is the best you can do.
The bigger question is why you want to generate all the codes at all. If all you want is to create a unique code per order number or something, you can make a state machine like:
function getNextCode(previousCode) {
// in here, just increment the previous code
}
If all you want is a random identifier, consider using a hash of the timestamp + something about the request instead.
If you don't care about uniqueness, you can always just generate a random code.
All of the above are O(1).

Javascript loop with dynamic start and end variables

This seems pretty basic, but I can't find the best method to do this... I'm trying to set up a function that loops between a user selected start and end variables. This is what I ended up with but I'm sure there is a better way to do it (demo).
Note: the x & y variables are indexed to one, not zero.
getWidths1 = function(x, y) {
var start = (x < y) ? x : y,
end = (x < y) ? y : x,
total = 0;
for (; start < end; start++) {
total += values[start - 1] || 0;
}
return total;
};
I tried this function, but the results are one result off when y > x:
getWidths2 = function(x, y) {
var total = 0,
diff = (x < y) ? 1 : -1;
while (x !== y) {
total += values[x - 1] || 0;
x += diff;
}
return w;
};
So, is the first function the best, or does someone have a better method?
The first isn't bad. I think this is slightly more traditional:
for (var i = start; i < end; i++){
}
Only real difference is that it doesn't affect start and end.
I'd make a few changes:
Use Math.min and Math.max - much more readable.
Don't subtract one from start if the first value you want is values[start].
var getWidths1 = function(x, y) {
var start = Math.min(x,y), end = Math.max(x,y);
var total = 0;
for (; start < end; start++) {
total += values[start] || 0;
}
return(total);
}
I agree with #kingjiv with the added caveat that if you want to include the item at y then you need:
for (var i = start; i <= end; i++){
...
}
As it is your code (both versions) will total the values from x inclusive to y exclusive.

Categories

Resources