配列のメソッド 高階関数 [JavaScript]

配列のメソッドについて、以前の投稿で書かせていただいたのですが、
高階関数の形を取る配列のメソッドについては言及していなかったので、
高階関数をまとめた上で、改めて高階関数の形を取る配列のメソッドについてもまとめておこうと思います。

また、高階関数とは？配列のメソッドの基本とは？と疑問に思われた方は、下記文章にて記載させて頂いております。

ご参考までに。

>参照：
>[配列　[JavaScript]](https://qiita.com/shisshi_engineer/items/a6c39764536fb960dda6)
>
>[高階関数の基本 [JavaScript]](https://qiita.com/shisshi_engineer/items/5a8d577d9eb3cf7a7a7a)
>

## 目次：
- [1. forEachメソッド](#1-foreachメソッド)
- [2. mapメソッド](#2-mapメソッド)
- [3. filterメソッド](#3-filterメソッド)
- [4. someメソッド](#4-someメソッド)
- [5. everyメソッド](#5-everyメソッド)
- [6. reduceメソッド](#6-reduceメソッド)

## 1. forEachメソッド

forEachメソッドは、関数を受け取り、配列内の要素１つ１つに対して、その指定した関数がよばれるというものです。


#### 1-1. forEachメソッドの例： numbersという配列の中身を１つ１つ出力するには？

numbers という配列の中に1から5の数字が入っています。

関数で、渡されたものを出力するという単純なprintという関数を作成します。

print関数：
１、print関数を定義。
２、パラメータをelementと設定。
３、elementをconsole.logで出力するように実行。

```js
const numbers = [1,2,3,4,5];

function print(element) {
    console.log(element);
}
```
numbersという配列に対して、forEachメソッドを使用する。
そして、forEachに対してprintという関数を渡す。
```js
numbers.forEach(print);
```

```text:出力結果：
1
2
3
4
5
```
forEachメソッドは、１つ１つの配列の中の要素に対して、print関数を呼び出してくれます。

:::note info
まとめ：

・forEachは関数を受け取る。
・forEachが受け取った関数を、各々の配列の要素に対して１つずつ呼び出す。
:::

#### 1-2. forEachメソッドの省略

関数を定義し、それをforEachに渡すよりも、定義を省略することもできます。
省略した形が、一般的な書き方です。
```js
const numbers = [1,2,3,4,5];
```

printという関数を定義している。
```js
function print(element) {
    console.log(element);
}
numbers.forEach(print);
```
print関数を定義せず、そのままforEachに渡している。
こちらの方が、スッキリとした見た目になります。
もちろん出力結果は同じです。
```js
numbers.forEach(function (element) {
    console.log(element);
}
```

```text:出力結果：
1
2
3
4
5
```
#### 1-3. for...ofループでも同様のことができる。

for...of構文は、配列や列挙可能なオブジェクトの要素を順番に処理をしていく際に、
とても便利な構文です。

>参照： [for...of ループ](https://qiita.com/shisshi_engineer/items/d17f4f2c8663dd0bb805#forof-%E3%83%AB%E3%83%BC%E3%83%97)

なので、forEachメソッドと同じような動作をすることができます。

先ほどの、numbersの配列の中身を全て出力する動作を、
for...ofループを使って再現してみます。

```js
const numbers = [1,2,3,4,5];

for(let element of numbers) {
    console.log(element);
}
```
forEachの構文と同じ結果を出力することができます。
```text:出力結果：
1
2
3
4
5
```

for...of構文と、forEachメソッドは似ていますが、
forEachはあくまで配列のメソッドである点に注意しましょう。

#### 1-4. 配列の中のオブジェクトにアクセスする。

forEachメソッドの応用例として、
moviesという配列の中に、titleとscoreに対してそれぞれ対応した値を入れたオブジェクトを用意しました。

この対応した値にアクセスして、映画のtitleとscoreを全て出力してみます。
scoreに関しては、100点中の対応するscoreと、それぞれの映画に対応した値を出力するようにします。

```js

const movies = [
    {
        title:"Detective Conan",
        score:99
    },
    {
        title:"ONE PIECE",
        score:90
    },
    {
        title:"DORAEMON",
        score:82
    },
    {
        title:"GUNDAM",
        score:88
    }

];
```
1.moviesに対してforEachメソッドをかける。
2.forEachメソッドが受け取る関数を定義する。
関数の内部
渡ってきたオブジェクトの要素１つ１つがmovieという変数の中に入る。

出力
console.logで、テンプレートリテラルを使用して出力します。
・movie.title
・movie.score
で、それぞれの渡ってきたオブジェクトに対応したtitleとscoreの値にアクセスして取得することができます。

```js
movies.forEach(function(movie) {
    console.log(`${movie.title} - ${movie.score}/100`);
})
```

## 2. mapメソッド

mapメソッドは、与えられた関数を配列の全ての要素に対して呼び出し、その結果からなる**新しい配列**を作成します。

#### 2-1. mapメソッドの例： numbersという配列の中身に2を掛けた値を、新しい配列として作成してみる。

numbers という配列の中に1から5の数字が入っています。
その値それぞれに２を掛けた値をmapメソッドを使って作成してみます。

```js
const numbers = [1,2,3,4,5];

const doubles = numbers.map(function(num) {
    return num * 2;
})
```
1. numbersという配列に、mapメソッドをかける。
2. コールバック関数を引数として渡してあげる。
コールバック関数に、引数として配列の中身の要素が一つずつ渡ってくるので、
パラメータ名をnumとしてあげる。
3. 各々の渡ってきた数字に対して2を乗算（掛ける）したものを返して(return)あげる。
4. 作成した配列を変数doublesに保存してあげる。 


```js
doubles
```
変数doublesの中身を確認すると、numbersの配列の中身に2を乗算(掛ける)した値が、
配列となって保存されているのを確認できます。

```text:出力結果：
2
4
6
8
10
```

#### 2-2. mapメソッドの例： 配列の中のオブジェクト要素を１部分だけ切り取った新しい配列を作成する。


先ほどのmoviesという配列の中のオブジェクトの例から、映画のtitleだけを摘出した新しい配列を作成したい場合。

mapメソッドを使用することで実現することができます。

```js

const movies = [
    {
        title:"Detective Conan",
        score:99
    },
    {
        title:"ONE PIECE",
        score:90
    },
    {
        title:"DORAEMON",
        score:82
    },
    {
        title:"GUNDAM",
        score:88
    }

];
```
1. moviesという配列に対してmapメソッドをかける。
2. mapメソッドに対してコールバック関数を定義する。
3. 1つ1つの映画のオブジェクトの要素が渡ってくるので、 movieというパラメーター名にする。
4. 1つ1つの映画のtitleが欲しいので、movie.titleをreturnしてあげる。
5. 返ってきた配列をtitlesという変数に保存する。 

```js
const titles = movies.map(function(movie) {
    return movie.title;
});

```

```js
titles
```
変数titlesの中身を確認すると、映画のtitleが配列で、入っていることを確認できます。
```text:出力結果：
["Detective Conan", "ONE PIECE", "DORAEMON", "GUNDAM"]
```

## 3. filterメソッド

filterにコールバック関数を渡し、そのコールバック関数は、
**true か false**を返すように設定します。
trueが返ってくるものに関しては、新しい配列に含まれ、falseの値に関しては無視されます。

#### 3-1. filterメソッドの例： numbersという配列の中身で、3より小さいものを出力する。

numbers という配列の中に、1から5の数字が入っています。
その値にfilter関数を使い、3より小さい値を取得する別の配列を作ってみます。

```js
const numbers = [1,2,3,4,5];

numbers.filter((num) => {
    return num < 3;
})
```
1. numbersという配列に、filterメソッドをかける。
2. コールバック関数を引数として渡してあげる。
コールバック関数に、引数として配列の中身の要素が一つずつ渡ってくるので、
パラメータ名をnumとしてあげる。
3. 各々の渡ってきた数字の中で、3より小さい数字を返して(return)あげる。

```js
[1,2]
```
また、コールバック関数は、１つの式のみを返す場合、暗黙的なreturnでreturnを削除したり、{}(波括弧)を省略して書くことができます。

```js
const numbers = [1,2,3,4,5];

numbers.filter(num =>return num < 3);
```

省略例：
1. numについている（）「丸括弧」を省略。
2. returnする関数式についていた{}「波括弧」を省略。
3. returnを省略。
4. 数字についていた ; 「セミコロン」を最後に移動。

```js
[1,2]
```

式自体、省略系で書いても回答結果は同一です。

## 4. someメソッド

配列内の要素の中で、どれか一つでもコールバック関数の結果を満たしていれば、trueになります。

#### 4-1.someメソッドの例： クラスの中に90点の点数をとっている人がいるかどうか。　trueを返す例。

テストの点数の結果を格納している配列examsがあります。

この配列examsの点数が90点以上の高得点者がいるかどうかを確認したい場合、someメソッドを活用できます。


```js
const exams = [80,90,91,99,100,77,79,75,89,88]

exams.every(exam => 90);
```
1. examsという配列に、someメソッドをかける。
2. コールバック関数を引数として渡してあげる。
コールバック関数に、引数として配列の中身の要素が一つずつ渡ってくるので、
パラメータ名をexamとしてあげる。
3. 各々の渡ってきた数字の中で、examが90よりも大きいかを確認する。
4. 確認した中の数字に一つでも90以上があれば、trueを返します。

※コールバック関数の短縮版で記載。

```js
true
```
#### 4-2.someメソッドの例： クラスの中に100点の点数をとっている人がいるかどうか。falseを返す例。
```js
const exams = [80,90,91,99,88,77,79,75,89,69]

exams.some((exam) => {
return exam >= 100;
})
```
1. examsという配列に、someメソッドをかける。
2. コールバック関数を引数として渡してあげる。
コールバック関数に、引数として配列の中身の要素が一つずつ渡ってくるので、
パラメータ名をexamとしてあげる。
3. 各々の渡ってきた数字の中で、examが100より大きいものがあるかどうかを確認する。
4. 確認した数字の中で、100を超えるものは１つもないので、falseを返します。
```js
false
```

## 5. everyメソッド

配列内の全ての要素が、指定された関数の結果を満たしているかどうかをtrueかfalseで返すメソッドです。

#### 5-1.everyメソッドの例： テスト結果が合格点かどうか。trueを返す例。

テストの点数の結果を格納している配列examsがあります。

この配列examsの点数が75点以上だったら合格、それ以下だったら不合格であるという結果を知りたい場合に、everyメソッドを活用できます。


```js
const exams = [80,90,91,99,100,77,79,75,89,88]

exams.every(exam => 75);
```
1. examsという配列に、everyメソッドをかける。
2. コールバック関数を引数として渡してあげる。
コールバック関数に、引数として配列の中身の要素が一つずつ渡ってくるので、
パラメータ名をexamとしてあげる。
3. 各々の渡ってきた数字の中で、examが75よりも大きいかを確認する。
4. 確認した全ての数字が75よりも大きければtrueを返す。

※コールバック関数の短縮版で記載。

```js
true
```
#### 5-2.everyメソッドの例： テスト結果が合格点かどうか。falseを返す例。
```js
const exams = [80,90,91,99,100,77,79,75,89,69]

exams.every((exam) => {
return exam >= 75;
})
```
1. examsという配列に、everyメソッドをかける。
2. コールバック関数を引数として渡してあげる。
コールバック関数に、引数として配列の中身の要素が一つずつ渡ってくるので、
パラメータ名をexamとしてあげる。
3. 各々の渡ってきた数字の中で、examが75よりも大きいかを確認する。
4. 確認した数字の中で、１つでも75以下の数字があればfalseを返す。

```js
false
```

## 6. reduceメソッド

reduceメソッドは、配列の各要素を合計した結果を求めるときなどに使用します。
※reduceメソッドは、与える関数により、様々な結果を返すので、複数の例を紹介していきます。

#### 6-1. 例: reduceメソッド、合計値を求める。

pricesという配列の中に複数の物の値段が入っています。
この配列の中身の合計値をreduceメソッドを使って求められます。

まずは、for...ofを使って求めてみます。
[参照：for...ofループの解説](https://qiita.com/shisshi_engineer/items/d17f4f2c8663dd0bb805#forof-%E3%83%AB%E3%83%BC%E3%83%97)

```js
const prices = [980, 1280, 2500, 3300, 5980]

let total = 0;

for(let pruce of prices) {
    total += price; 
};

console.log(total);

```
pricesの中身、980、1280、2500、3300、5980の中身を合計した値、
14040が出力結果として表示されます。

```text:出力結果：
14040
```

#### 6-2. 例： reduceメソッドを使用する場合。

```js
const prices = [980, 1280, 2500, 3300, 5980]

prices.reduce((total, price) => {
    return total+= price;
})
```
 1. 配列、pricesに対してreduceメソッドをかける。
 2. コールバック関数のパラメータの最終的な値として、（total）、2つ目の値として、（price）を書きます。
 3. returnするものとして、totalと各々の値priceを書きます。
 3-1. totalには最初の値として980が入ります。
 3-2. priceには最初の値として1280が入ります。
 3-3. returnされたtotalの値には、この合計値(2260)が入り、priceには、次の値(2500)、(3300)、(5980)と、配列が終わるまでpriceに順番に入りtotalの合計値：14040となります。

```text:出力結果：
14040
```
コールバック関数を省略して書くこともできます。
```js
prices.reduce((total, price) => total += price)
```

```text:出力結果：
14040
```

#### 6-3. 配列内の最小値を求める。

reduceメソッドを使って、配列内の最小値を求めることもできます。

```js
const prices = [980, 1280, 2500, 3300, 5980]

const minPrice = prices.reduce((min, price) => {
    if(min > price) {
        return price;
    }
    return min;
})

minPrice
```
 1. 配列、pricesに対してreduceメソッドをかける。
 2. コールバック関数のパラメータの１つ目の値として、（min）、2つ目の値として、（price）を書きます。
 3. if文を書きます。
 3-1. もし、minの値がpriceより低ければ、returnとしてpriceを返します。
 （minとpriceには、配列の値がそれぞれ入り、比較されます。）
 (例：「980 > 1280 = 980がmin 」 「980 > 2500 = 980がmin」 ) 
 3-2. 比較される値がなくなれば、それが最小値になるので、minを最小値として返します。
 
 4.求めた値をminPriceとして変数に保存して使うこともできます。

```text:出力結果：
980
```

#### 6-4. 配列内の最大値を求める。

reduceメソッドを使って、配列内の最大値を求めることもできます。
(例6-3.のminとは逆の不等号（<）を使用するだけで最大の出力結果を求めることができます。)

今回は、最大値の値を変数maxPriceとし、最大値の入るパラメータの値をmaxとしています。

```js
const prices = [980, 1280, 2500, 3300, 5980]

const maxPrice = prices.reduce((max, price) => {
    if(max < price) {
        return price;
    }
    return max;
})

maxPrice
```
 1. 配列、pricesに対してreduceメソッドをかける。
 2. コールバック関数のパラメータの１つ目の値として、（max）、2つ目の値として、（price）を書きます。
 3. if文を書きます。
 3-1. もし、maxの値がpriceより大きければ、returnとしてpriceを返します。
 （maxとpriceには、配列の値がそれぞれ入り、比較されます。）
     (例：「980 < 1280 = 1280がmax」 「1280 < 2500 = 2500がmax」 ) 
 3-2. 比較される値がなくなれば、それが最大値になるので、maxを最大値として返します。
 
 4.求めた値をmaxPriceとして変数に保存して使うこともできます。

```text:出力結果：
5980
```