0

I've been running JSLint over some code, and dealing with some of the issues it throws up. One of those was

Unexpected 'for'.

The code has to work over different subsets of an array, depending on what the user has asked for. As an example we might have

myArray = [1,2,3,4,5,6,7,8,9];
let start = 4;
let finish = 8;
let i;
for (i=start; i<finish;i++) {
    // Do stuff with myArray[4] to myArray[7]
}

What is JSLint's objection to this construction?

How would I achieve that without using a for loop?

Note: I know I could disable the warning in JSLint, or that I could simply ignore the warning, but that just circumvents the issue.

  • Check out [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) if you want to iterate an array and cause side effects. – Mark Jun 20 '17 at 01:13
  • @Mark I thought of that, but Array.forEach() always iterates over the entire array. I could filter inside the function but that seems really counter-intuitive. –  Jun 20 '17 at 01:20
  • @Airsick, you can use a method like [Array.slice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) to get the exact range you need. – Mark Jun 20 '17 at 01:27
  • @Mark I see that Bergi has suggested exactly that. See my comments on his answer –  Jun 20 '17 at 01:51

3 Answers3

2

You can use

myArray.slice(start, finish).forEach(el => {
    …
});

to comply with JSlint's rules.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I can see that this would meet Douglas Crockford's desire to do away with loops, but I'd be concerned about performance. How would this perform if the source array is large and the slice is of a similar order of magnitude? Would there be any significant difference for arrays smaller than thousands of elements? –  Jun 20 '17 at 01:45
  • Please do not understand my answer as an endorsement of the JSlint rules, or an advise to use this code - it only shows a way to comply with the rules if you chose to follow them. Personally I even hold the exact opposite view - when you really need an imperative loop, a loop construct should be used to stand out instead of hiding it in `forEach` call. But no, I wouldn't be concerned about performance, any loop is `O(n)`, and the slice doesn't make it worse. (Of course a `for` loop is faster than `.forEach`) – Bergi Jun 20 '17 at 03:09
  • I find JSLint useful for some things, but I find its pedantry annoying at times, and although Douglas Crockford has some useful ideas, I have found them sometimes to be restrictive at best. I'd considered the .slice() approach but thought there must be a more intuitive way of doing things. For this I'll continue to use the constructs that have served me well for decades. Thanks for your input. –  Jun 20 '17 at 04:42
0

You could accomplish the same thing with a while pretty easily as well.

myArray = [1,2,3,4,5,6,7,8,9];
let start = 4;
let finish = 8;
let i = start;
while (i < finish) {
  // Do stuff with myArray[4] to myArray[7]
  i++;
}
snollygolly
  • 1,858
  • 2
  • 17
  • 31
  • 1
    Strictly, this isn't a 'for' loop so I suppose it qualifies, but a rose by any other name... If I were reading this code next month my first thought would be 'Why did I do that?' –  Jun 20 '17 at 01:42
  • That's what comments are for ;) – snollygolly Jun 20 '17 at 01:43
0

Dude it's because your hoisting the 'i'.

var myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let start = 4;
let finish = 8;
for (start; start < finish; start++) {
  console.log(start);
}
Rick
  • 1,035
  • 10
  • 18
  • Not the point. My questions is not about the specifics of the example, but why and how to achieve the same result without a 'for' loop. –  Jun 20 '17 at 01:39
  • @Airsick you asked, "What is JSLint's objection to this construction?". Also, there too many ways to iterate for any answer to be meaningful to such an open ended question. – Rick Jun 20 '17 at 01:46
  • 1
    I just ran this snippet through JSLint. It raises the same objection, so whatever the reason is, it's not related to hoisting the i. –  Jun 20 '17 at 01:50
  • Ok then use a less efficient loop, I'm sure js lint will thank you for your compliance. – Rick Jun 20 '17 at 02:40