tags:

views:

109

answers:

6

How to put the k var in the for-loop construction. I want more compact code, not like this one:

var k = 0;
for (var i = 0; i < arr.length; i++) {
   if (arr[i] == 'x') {
       k++;
   }
}
+2  A: 

Add it to the first clause in the for statement, separated by a comma:

   for (var i = 0, k = 0; i < mystick.length; i++) {
      if (mystick[i] == 'huge') {
          k++;
      }
   }
Andy E
Shouldn't that be `k = 0`?
WoLpH
well, you'd want to assign 0 to k also
Scott Evernden
@WoLpH: Yes... yes it should. I was too busy concentrating on editing the offensive parts :-)
Andy E
@Andy E, Does not k become a global variable here?
Anders
@Anders: no, it doesn't. It's contained in the same `var` statement so it's a local variable to the for loop. Just like `i` is.
WoLpH
@WoLpH, of course I should have noticed that!
Anders
No, `k` and `i` are not local to the `for` loop! This is javascript. There is only global and function scope!!
Gabe Moothart
@Anders: both the `k` and the `i` are bound to the scope they are created in, that is, either a containing function or the global scope. As @Gabe pointed out, if the `for` loop is in the global scope, then both the `k` and the `i` become global variables (which is why it's bad practice to use for loops in the global scope and another reason to always use the `var` keyword).
Andy E
+3  A: 

Although not as efficient due to the fact that a new array is constructed, using filter leads to far more compact code.

arr.filter(function(e){ return e == 'x'; }).length;

An alternative, although far less clear avoids constructing a new array:

arr.reduce(function(x, e){ return x + (e == 'x' ? 1 : 0); }, 0);
Yacoby
...and none of these prototype methods exist in IE8 and lower, so it becomes even less compact when you have to add them yourself :-)
Andy E
To an extent it is a valid point, however you don't know what the use of the code is. I have just written a load of code targeting a single browser. If in doubt I am going to assume the newest standard *shrug*
Yacoby
+1 even though these native methods aren't in all browsers, they are provided by any js framework, which you should be using anyway. And the code is much clearer.
Gabe Moothart
+1  A: 

You should also measure the length of the stick in the first part of the for loop, otherwise you'll be measuring it with every iteration. And you can also make the k bit even more compact:

for (var i = k = 0, j = mystick.length; i < j; i++) {
      if (mystick[i] == 'huge') {
          k++;
      }
   }
Rafael
The length is a property, not a method. So, I guess no extra measurement will take place because it has already happened at the moment of the whole iteration. Also, caching the length might cause unpredictable results in case the array gets changed while iterating.
Alex Polo
+1  A: 

Just to keep things interesting, how about a completely different (and slightly faster since decrementing while loops tend to perform a little better in javascript) method.

var i = arr.length;
while(i--){
  if(arr[i] == 'x')k++;
}
WoLpH
+2  A: 

Not so readable, but seems to work:

for (var i = 0, k = 0; i < mystick.length; i++) {
    mystick[i] == "huge" && k++;
}

Here's a single liner (even uglier):

for (var i = k = 0; i < mystick.length; i++, mystick[i] == "huge" && k++);
Helgi
+2  A: 

Because this is javascript and javascript doesn't have block scope, it is actually best practice to do the opposite - declare both i and k outside the body of the for loop, at the top of the function or script block. This way you don't trick yourself into thinking i is restricted to the for loop. You could still initialize both in the body of the for loop, as others suggest:

var k,
    i;
...

for (i = 0, k = 0; i < arr.length; i++) {
    if (arr[i] == 'x') {
        k++;
    }
}
Gabe Moothart