Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Start from second item in forEach loop

I need to start from second item in array. In order to save correct context I need to use forEach instead of simple for loop.

I've done it in next way :

private convertToRanges(arr: []): any[] {
        const inputArr = arr.slice(),

        if (inputArr.length > 1) {
            let lastIndex = 0;
            inputArr.shift();
            inputArr.forEach(item => {
                ...
            });
        }
        ...
    }

I make copy and remove first item in copy.

Is there another way to start from second item and be context sure?

like image 211
demo Avatar asked Dec 22 '16 12:12

demo


1 Answers

You can't tell forEach where to start, no, but you can ignore the calls you don't want:

inputArr.forEach((value, index) => {
    if (index < 1) return;
    // Code from here onward will only run for entries that aren't
    // the first entry
});

Or if you're not worried about copying most of the array, you can always use slice:

inputArr.slice(1).forEach(value => {
    // ...
});

You could also define your own forEach-style function accepting a starting index, if you liked, making it non-enumerable and choosing the name carefully to avoid conflicts.

It's also perhaps worth noting that since you're using ES2015, some of the reasons for using forEach go away a bit thanks to block scope. for is still a bit more verbose than forEach with an arrow function, but lets you start and end and increment by whatever you like:

for (let i = 1; i < inputArr.length; ++i) {
    // ...`i` and also any `let` or `const` here are scoped to
    // this specific loop iteration...
}

The part about i above is primarily a good thing, but also has a slight performance impact (at least for now) since a new i has to be created for each iteration. Not that that performance impact usually matters at all, though, and it won't be as big as calling a function a'la forEach.

Gratuitous example of the above:

const inputArr = ['a', 'b', 'c', 'd'];
for (let i = 1; i < inputArr.length; ++i) {
  // A closure to emphasize that each `i` is distinct
  setTimeout(() => {
    console.log("inputArr[" + i + "] = " + inputArr[i]);
  }, 0);
}

(Normally I'd use a template literal there, but wanted to avoid giving the impression the i behavior related to that.)

like image 100
T.J. Crowder Avatar answered Sep 24 '22 14:09

T.J. Crowder