JavaScriptの配列のメソッドの使い方～filter・map・findIndex・find・splice・slice～

# 記事の目的

ども、[N予備校](https://www.nnn.ed.nico/)でプログラミングをせっせせっせと勉強中のふーちんでーす
この記事ではJavaScript配列関係のメソッドの使い方、4つ紹介・説明しまーす。
今までは、「`push`と`join`ならわかるけど、、？」みたいな状態でした。
そして最近、N予備校で勉強中に、`filter`メソッド、`map`メソッド、`findIndex`メソッド、`splice`メソッドが出てきました。
N予備校の教材をよく読んだら大体はわかりました、が、それでもちゃんと分かっている気がしなかったので、
Qiitaの記事を書いて説明できるか試してみました。
（ついでにfindとsliceメソッドも追加した）

# 目次

- [1つ目、filterメソッド](https://qiita.com/fuuchin/items/8c14164cb4ef886f09e0#filter)
- [2つ目、mapメソッド](https://qiita.com/fuuchin/items/8c14164cb4ef886f09e0/#map)
- [3つ目、findIndexメソッド](https://qiita.com/fuuchin/items/8c14164cb4ef886f09e0/#findIndex)
- [4つ目、findメソッド](https://qiita.com/fuuchin/items/8c14164cb4ef886f09e0/#find)
- [5つ目、spliceメソッド](https://qiita.com/fuuchin/items/8c14164cb4ef886f09e0/#splice)
- [6つ目、sliceメソッド](https://qiita.com/fuuchin/items/8c14164cb4ef886f09e0/#slice)

# filter

[MDNはこちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)

##### 《 おもなメソッドの役割 》

① 配列の`全ての要素に条件をかける`。
② 条件に当てはまった要素のみが、代入する配列に入れられる。

まさにフィルターにかけている感じ。

呼び出された`元の配列は何も変化しない`。使われるだけ。

```javascript: サンプルコード：3の倍数を探せ
const numbers = [3, 7, 8, 12, 15, 20];

// 3の倍数だけ残します
const threeMultiple = numbers.filter(function(n) {
    return n % 3 === 0; // この条件に当てはまった数字がthreeMultipleに残る
});
console.log(threeMultiple); // [3, 12, 15] ← 3の倍数が条件に当てはまるので、配列に残った！
console.log(numbers); // [3, 7, 8, 12, 15, 20] ← 元の配列は何も変わんない！
```
ここの
```javascript
const threeMultiple = numbers.filter(function(n) {
    return n % 3 === 0;
});
```
のコードは簡単に書くことができ、`function`を使わずにアロー関数で実装すると、
```javascript
const threeMultiple = numbers.filter((n) => {
    return n % 3 === 0;
});
```
こうなり、
引数が一つのときは、`(n)`を`n`にでき、
returnで返す内容が、一つの式で表せられるので、`return`と`{}`を同時に省き、
最終的に
```javascript
const threeMultiple = numbers.filter(n => n % 3 === 0);
```
こうなります。


# map

[MDNはこちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

##### 《 おおまかなメソッドの役割 》

① 配列の全ての要素に`同じ処理をする`。
② 処理の結果の配列が返ってきます。

配列のすべての要素を編集したいときに使えそうな感じ。

これも、呼び出された`元の配列は何も変化せず`、使われるだけ。

**※連想配列のMapとは名前だけ似てる全然違うやつです**

サンプルコードは2種類用意してみました。

```javascript: 1種類目：さん付けプログラム
const users = ['太郎', '次郎', '三郎', '寝太郎'];

// さん付けする関数です
const sandukeUsers = users.map(function(name) {
    return name + 'さん'; // 要素一個一個に「さん」を足していく
});
console.log(sandukeUsers); // ['太郎さん', '次郎さん', '三郎さん', '寝太郎さん'] ← 全部の要素に「さん」が足された！
console.log(users); // ['太郎', '次郎', '三郎', '寝太郎'] ← 元の配列は何も変わんない！
```

これも、アロー関数使ったり、かっこや`return`を省いたりすると、
```javascript
const sandukeUsers = users.map(name => name + 'さん');
```
と、表せられます。
このプログラムは、全部の要素にある値を追加した例でした。

2種類目は、取得で編集バージョンです。

```javascript: 2種類目：年齢だけ取得プログラム
const users = [
  { name: '太郎', age: 32 },
  { name: '次郎', age: 25 },
  { name: '三郎', age: 16 },
  { name: '寝太郎', age: 38 }
];

// 年齢だけの配列を代入
const getAge = users.map(function(user) {
    return user.age; // 要素一個一個の年齢プロパティを取得して返す
});
console.log(getAge); // [32, 25, 16, 38] ← ageプロパティだけが取られた配列！
console.log(users); // [{...}, {...}, {...}, {...}] ← 元の配列は何も変わんない！
```

これも、アロー関数使ったり、かっこや`return`を省いたりして、
```javascript
const getAge = users.map(user => user.age);
```
と、表せられます。

# findIndex

[MDNはこちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex)

##### 《 おもなメソッドの役割 》

① 渡した関数`（条件）に当てはまる`（trueが返る）配列の要素がないか`順番に見て探していく`。
② あったらの`配列のインデックス`が返ってくる。
③ 見つからなかった場合は`-1`が返ってくる。
④ trueが返る配列の要素がいくつもある場合は、最初に見つかったインデックスが返ってくる。

`filter`との違いは、
`filter`: 条件に合ってる要素を集めた配列を返す
`findIndex`: 条件に合ってる要素があるか、あったら**インデックス**を返す

```javascript: サンプルコード：寝太郎を探せ
const group1 = ['太郎', '次郎', '寝太郎', '三郎', '花子']; // 寝太郎が1つ
const group2 = ['トム', 'パーシー', 'マイク', 'ジョン']; // 寝太郎ナシ
const group3 = ['太一', '五郎', '三四郎', '寝太郎', '銀次郎', '寝太郎']; // 寝太郎が2つ

// 寝太郎を探し、あればインデックスを代入
const findNetaro1 = group1.findIndex(function(name) {
    return name === '寝太郎'; // 要素一個一個、寝太郎と条件判定
});
console.log(findNetaro1); // 2 ← 2番目の要素（3番目）に寝太郎があった！

// 寝太郎ナシで試すバージョン
const findNetaro2 = group2.findIndex(function(name) {
    return name === '寝太郎'; // 要素一個一個、寝太郎と条件判定
});
console.log(findNetaro2); // -1 ← 見つからんかったから-1！

// 寝太郎2つで試すバージョン
const findNetaro3 = group3.findIndex(function(name) {
    return name === '寝太郎'; // 要素一個一個、寝太郎と条件判定
});
console.log(findNetaro3); // 3 ← 5番目（6番目）にも寝太郎があるけど、それより先にあった、3番目の要素（4番目）の寝太郎！
```
はいこれも、簡略化すると、
```javascript
const findNetaro1 = group1.findIndex(name => name === '寝太郎');
```
という風になります。

因みに、このようなプログラムであれば、indexOfメソッドを使った方が簡潔にできるかもしれません。
特有の条件を使う場合は、findIndexを使った方がよいのかもしれません。

ちなちな因みに、
findLastIndexメソッドというものもあります。それは、最後の要素から見て探します。

https://qiita.com/fuuchin/items/3081c84b5659b3d78bf6#findlastindex

# find

[MDNはこちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find)

##### 《 おもなメソッドの役割 》

① 渡した関数`（条件）に当てはまる`（trueが返る）配列の要素がないか`順番に見て探していく`。
② あったらの`配列の要素` が返ってくる。
③ 見つからなかった場合は`undefined`が返ってくる。
④ trueが返る配列の要素がいくつもある場合は、最初に見つかった要素が返ってくる。

findIndexとの違いは、
findIndex: 条件に合ってる要素があるか、あったら**インデックス**を返す
find: 条件に合ってる要素があるか、あったら**要素**を返す

```javascript: サンプルコード：寝太郎の年齢を取得
const users = [
  { name: '太郎', age: 32 },
  { name: '次郎', age: 25 },
  { name: '三郎', age: 16 },
  { name: '寝太郎', age: 38 }
];

// 寝太郎を探し、あればインデックスを代入
const findNetaro = users.find(function(user) {
    return user.name === '寝太郎'; // 要素一個一個、寝太郎と条件判定
});
console.log(findNetaro); // {name: '寝太郎', age: 38} ← 要素はこれのこと！
console.log(findNetaro.name); // 寝太郎
console.log(findNetaro.age); // 38
```
はいこれも、簡略化すると、
```javascript
const findNetaro = users.find(user => user.name === '寝太郎');
```
という風になります。

因みに、
findLastメソッドというものもあります。それは、最後の要素から見て探します。

https://qiita.com/fuuchin/items/3081c84b5659b3d78bf6#findlast

# splice

[MDNはこちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)

##### 《 おもなメソッドの役割 》

① 配列要素を取り除いたり、置き換えたり、新しい要素を追加したりできる。
② 第1引数に入れる値は、`削除する位置の始まり`のインデックス。
③ 第2引数には、`削除する要素の個数`（0ってのも有り）。
④ 第3引数には、代わりに入れる要素（なくってもいい、省略可能ってこと）。

元の配列を編集するので、実装後、`元の配列の値は変わります`。

サンプルコードを3種類載せようと思います。

```javascript: 1種類目：寝太郎を削除し太郎
const users = ['太郎', '次郎', '花子', '寝太郎', '寝太郎', '三郎', '太一'];
users.splice(3, 2); // 3番目の要素から2つ消す
console.log(users); // ['太郎', '次郎', '花子', '三郎', '太一'] ← 元の配列が変わってる！
```

```javascript: 2種類目：寝太郎を増やし太郎
const users = ['太郎', '次郎', '花子', '寝太郎', '三郎', '太一'];
users.splice(1, 0, '寝太郎'); // 1番目の要素から要素は消さずに、寝太郎を挿入
console.log(users); // ['太郎', '寝太郎', '次郎', '花子', '寝太郎', '三郎', '太一'] ← 次郎の前に入った！
```

```javascript: 3種類目：寝太郎を消した代わりに「もっと寝太郎」を追加し太郎
const users = ['太郎', '次郎', '花子', '寝太郎', '三郎', '太一'];
users.splice(3, 1, 'もっと寝太郎'); // 3番目の要素から一つ消し、「もっと寝太郎」を挿入
console.log(users); // ['太郎', '次郎', '花子', 'もっと寝太郎', '三郎', '太一'] ← 「もっと寝太郎」と入れ替わった！
```

このように使うんですが、その前に紹介したメソッドとは違い、変数に代入などしては使いませんでした。
変数に代入した場合は、戻り値が入るのですが、戻り値として、何が返ってくるのでしょうか。

```javascript: 戻り値なんやろ：寝太郎を削除し太郎
const users = ['太郎', '次郎', '花子', '寝太郎', '寝太郎', '三郎', '太一'];
const returnValue = users.splice(3, 2); // 3番目の要素から2つ消す、戻り値を代入
console.log(returnValue); // ['寝太郎', '寝太郎'] ← 削除した寝太郎2つ！
```
はいこのように、削除した要素が、配列の状態になって返ります。
因みに、削除した要素数が0の場合は、空の配列が返ります。

# slice

[MDNはこちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)

##### 《 おもなメソッドの役割 》

◎ 配列の指定した部分をコピーする。

まさにスライスして、その後にコピーする。てな感じ。

呼び出された`元の配列は何も変化しない`。使われるだけ。

サンプルコード3つ用意しました。

```javascript: サンプルコード1：コピーしよう
const text = ['aaa', 'aaa', 'ここを', 'コピー', 'するよ', 'aaa'];

// 要素3つをコピーするよ
const textCopy = text.slice(2, 5);

console.log(textCopy); // ['ここを', 'コピー', 'するよ'] ← 5番目とあるが、コピーされるのは4番目まで！
console.log(text); // ['aaa', 'aaa', 'ここを', 'コピー', 'するよ', 'aaa'] ← 元の配列は何も変わんない！
```

```javascript: サンプルコード2：配列そのままコピーしよう
const text = ['hoge', 'piyo', 'foo'];

// 配列ごとそのままコピーするよ
const textCopy = text.slice(); // ← 引数ナシ

console.log(textCopy); // ['hoge', 'piyo', 'foo'] ← 引数ナシだと、スライスせずに、配列がコピーされた！
```

```javascript: サンプルコード3：配列の最後からコピーしよう
const text = ['aaa', 'aaa', 'aaa', 'aaa', 'ここを', 'コピー', 'するよ'];

// 最後から3番目以降すべてコピーするよ
const textCopy = text.slice(-3);

console.log(textCopy);
// ['ここを', 'コピー', 'するよ'] ← マイナスの値を入れると、最後から数えて要素がコピーされた！
//                                 引数を1つだけ入力したら、 最後までコピーされた！
```
ちなみに、負の値はspliceメソッドでも使えます。
#### 最後に

ほかのメソッドもまた別の記事などに追加していこうと思います。

ありがとうございました～