# { Additional Array Methods. }

### Objectives:

By the end of this chapter, you should be able to:

• Use `some` and `every` to iterate through an array and return a boolean.
• Use `find` and `findIndex` to locate elements and indexes in an array.
• Understand how to chain/combine iterators to write more complex code
• Explain the advantages and drawbacks of using iterators versus loops
• Determine when to use certain array methods based on the problem you are trying to solve

### some

To figure out if ANY single value satisfies a condition in an array, we can use the `some` function. This will return `true` if ANY value passes a condition specified in the callback, and `false` if all values fail the condition.

```var arr = [1,2,3,4];

var anythingGreaterThanTwo = arr.some(function(val){
return val > 2;
});

var anyStrings = arr.some(function(val){
return typeof val === "string";
});

anythingGreaterThanTwo; // true
anyStrings; // false
```

You can read more about `some` here.

### every

To figure out if ALL values satisfy a condition in an array, we can use the `every` function. This will return `true` if ALL values pass a condition specified in the callback. If even one value fails the condition, `every` will return `false`.

```var arr = [1,2,3,4];

var everythingGreaterThanTwo = arr.every(function(val){
return val > 2;
});

var everythingLessThanFive = arr.every(function(val){
return val < 5;
});

everythingGreaterThanTwo; // false
everythingLessThanFive; // true
```

You can read more about `every` here.

### find

`find` was added to JavaScript in ES2015 to make it easier to find an element in an array based on some condition. This iterator will return the first value in an array that satisfies a condition (an expression that returns `true` in the callback).

```var arr = [-3,1,8,4];
var firstValueGreaterThanTwo = arr.find(function(val){
return val > 2;
});

firstValueGreaterThanTwo; // 8
```

You can read more about `find` here.

### findIndex

To find the first index in an array that satisfies a condition (an expression that returns `true` in the callback) - we can use the `findIndex` function.

```var arr = [-3,1,8,4];
var firstIndexOfElementGreaterThanTwo = arr.findIndex(function(val){
return val > 2;
});

firstIndexOfElementGreaterThanTwo; // 2
```

You can read more about `findIndex` here

### Combining Iterators

By combining iterators, you can often manipulate arrays using a sequence of very simple functions, rather than one larger, more complex loop. For example, suppose you wanted to take an array of numbers, filter out the even ones, double the remaining values, and then add everything up. We can do this by chaining three iterators together:

```var arr = [1,2,3,4,5]
arr.filter(function(val){
return val % 2 !== 0; // only keep odd numbers
}).map(function(val){
return val * 2; // double remaining values
}).reduce(function(acc,next){
return acc + next; // add everything up
},0) // 18
```

This sort of chaining helps keep your code easy to reason about, because each callback is only responsible for one thing. To make things even more readable, you could give names to the callbacks:

```var arr = [1,2,3,4,5];

function isNumberOdd(val) {
return val % 2 === 1;
}

function doubleValue(val) {
return val * 2;
}

function sum(a,b) {
return a + b;
}

arr.filter(isNumberOdd)
.map(doubleValue)
.reduce(sum,0); // 18
```

By keeping the code inside of our functions simple, we can reduce (no pun intended) the likelihood that we'll introduce bugs into our code, and when we come back to our code weeks or months later, it'll hopefully be easier for us to wrap our heads around.

### Additional note and refactoring when using iterators

Just because JavaScript has a lot of different iterators, this doesn't necessarily mean you should always use an iterator in place of a `for` loop. One of the biggest advantages to using a for loop is that you can break out of the loop or continue to the next iteration using the keywords `break` and `continue`. If you try to use these keywords inside of an iterator, however, you'll get a `SyntaxError`.

Now that you've seen some iterators, let's highlight some situations when you might want to use one over another. If you're used to writing `for` loops you'll probably be most likely to use `forEach`, but this isn't always the best iterator for the job:

```var arr = [1,2,3]

// using forEach

var newArr = [];
arr.forEach(function(val){
newArr.push(val*2);
});

// In the above example, we're creating a new array
// with the same length as the old array. So instead
// of forEach, we can refactor to use map:

var newArr = arr.map(function(val){
return val*2;
});
```
```var arr = [1,2,3]

// using forEach
var newArr = [];
arr.forEach(function(val){
if(val >= 2){
newArr.push(val);
}
})

// In the above example, we're creating a smaller array.
// We're also not changing any values. So instead
// of forEach, we can refactor to use filter:

// refactor to use filter
var newArr = arr.filter(function(val){
return val >= 2;
})
```

Before using an iterator, it's always good to ask whether `forEach` is the best candidate for the job, or whether another iterator would be more appropriate. If you're trying to manipulate values in an array to return a new array of the same length, `map` is probably a better choice. If you're trying to remove some elements in the array and keep others, `filter` is more likely the way to go. And if you're looking to take an array and output some other value (a number, a string, an object, etc.), consider whether or not you can use `reduce` to get the job done.

When you're ready, move on to Iterators Exercises