Anna F
Anna F

Reputation: 1683

How to exclude an array of indexes from loop

I have an array y like this:

var y = [1, 2, 3, 4];

And I would like to iterate through the array, but exclude some indexes. The indexes are saved in second array

var x = [1,3];

So, I want to write each numbers from an array y, but not the numbers on the position 1,3, which come from array x

I tried to skip the numbers on these positions, but with no success. Could you please help me? Here is what I tried

for (var i = 0; i < y.length; i++) {
    for (var j = 0; j < x.length; j++) {
            if (i === x[j]) {
        continue;
     } 
    }
 console.log(y[i]);
}

Upvotes: 2

Views: 2807

Answers (3)

toastal
toastal

Reputation: 1073

Short answer

Prefer using filter over a loop (unless performance is critical & the loop benchmarks to a meaningful gain over the Array filter method which doesn’t introduce state)

const xs = [ 1, 2, 3, 4, 5 ]  // array of values
const ys = [ 1, 3 ]           // indices to skip

// using `filter`
const zs = xs.filter((_, i) => !ys.includes(i))

console.log(zs)
//=> [ 1, 3, 5 ]

Long answer

When possible, you don’t want to be using a loop because it can hurt the ability to understand your code taking a procedural approach over a declarative approach. You can instead use a higher-order function like Array.prototype.filter to keep the values you want. The return value of the function passed into filter needs to return a boolean of what to keep. In JavaScript, the filter function is of binary arity, meaning it takes two arguments, with the first argument being the array element and the second being the index. We can ignore the array element value as it is only the index we need to check (this is why the function starts with (_, ...) to drop the first argument).

Array.prototype.includes is a function on the array prototype that lets you know if the array contains a value (i.e. [0].includes(0) === true and [0].includes(1) == false).

Putting these two concepts together, we can iterate over the first array, xs, ignoring the values but using the index to see if it's included in our blacklisted indices array, ys.

If we looked at this as a map function, instead of filter that included our value

xs.map((v, i) => [ v, !ys.includes(i) ])
//=> [ [ 1, true ], [ 2, false ], [ 3, true ], [ 4, false ], [ 5, true ] ]

We can see which values will be true. And if we remember, filter keeps our true values [ 1, 3, 5 ].

Upvotes: 7

dwjohnston
dwjohnston

Reputation: 11781

You could use the Array.includes() method.

var list = [1,2,3,4];
var skipIndexes = [1,3]; 

for (var i = 0; i< list.length; i++) {
 if (! skipIndexes.includes(i)) {
  console.log(list[i]); 
 }
}

Upvotes: 3

CRice
CRice

Reputation: 32146

Looks like you were pretty close, but you don't need the inner loop. Just check if the index you're on (i) is one of the members of the array x, and if so, continue. You can do that using the array .includes method, or indexOf if you don't have es6 support.

var y = [1, 2, 3, 4];
var x = [1,3];

for (var i = 0; i < y.length; i++) {
    if (x.includes(i)) continue; // Or if not es6 use: `x.indexOf(i) !== -1`
    console.log(y[i]);
}

This prints 1 and 3, which are the items of the array y in the 0th and 2nd indices respectively (since we skipped indices 1 and 3).

Upvotes: 2

Related Questions