【初心者向け】ES6含むJavaScript配列まとめ

JavaScript(ES6含)の配列操作をまとめてみました！

初心者向けに厳密さよりも、分かりやすさ重視の言い回しで書いています。
正確な情報はMDNを適宜ご確認ください→ [Array | MDN web docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array)

**ちなみに`*`のついている書き方は配列を「破壊的操作」します。**
**「破壊的な」メソッドはもとの配列を直接操作して変更（破壊）してしまうことを意識してください！**

エンジニア歴2週間の初心者なので、間違いがあったらご指摘いただけると嬉しいです:pray:

## 追加（push*, splice*）
### push*
新しい要素を配列の末尾に追加できます
pushの代わりに`unshift`を使うと配列の先頭に追加できます

```sample.js
const arr = ['apple', 'plum', 'melon'];
arr.push('banana');
console.log(arr);
// 結果： ["apple", "plum", "melon", "banana"]
```
（splice*は次の「削除」項目で説明）

##複製（assign, スプレッド構文）
上記のように「追加」したいけど破壊的変更をしたくないときは複製します
### assign
JavaScriptは配列やオブジェクトは参照渡しになります
下記のように複製して変更をすることで新しいオブジェクトを作ることができます
参考：[【Javascript】値渡しと参照渡しについてあらためてまとめてみる](https://qiita.com/migi/items/3417c2de685c368faab1)

```sample.js
const obj = { id: 1, name: 'apple' };
const obj2 = Object.assign({}, obj);
obj2.name = 'banana';

console.log(obj); // 結果：{id: 1, name: "apple"}
console.log(obj2); // 結果：{id: 1, name: "banana"}
```
（オブジェクトの中に１段深い配列があると参照渡しになってしまうので注意です）
### スプレッド構文
スプレッド演算子「...」をつけると配列に要素を追加することができます
ArrayはES2015から、ObjectはES2018から使えるようになりました

```sample.js
const arr = ['apple', 'plum'];
console.log(...arr, 'peach', 'lemon');
// 結果："apple" "plum" "peach" "lemon"

const obj = { aomori: 'apple', yamanashi: 'plum' };
console.log({ ...obj, shizuoka: 'orange' });
// 結果：{aomori: "apple", yamanashi: "plum", shizuoka: "orange"　}
```

## 削除（pop*, shift*, splice*）
### pop*
配列の末尾の要素を削除し、削除した要素が`pop()`で返ってきます
popの代わりに`shift`を使うと、配列の先頭の要素が削除できます

```sample.js
const arr = ['apple', 'plum', 'melon'];
console.log(arr.pop());
// 結果：melon
```

### splice*
配列の任意の位置に要素を追加したり、削除したりできます
`splice([何番目の要素に],[削除する数],[追加する要素])`で指定ができます

```sample.js
const arr = ['apple', 'plum', 'melon'];
arr.splice(2, 0, 'lemon'); // 2番目の要素に追加（削除は0）
console.log(arr);
// 結果：["apple", "plum", "lemon", "melon"]
```

## 連結（concat）
### concat
配列同士を繋げて、新しい配列をつくることができます
先述したスプレッド構文でも同じ結果を得られます

```sample.js
const arr1 = ['apple', 'plum'];
const arr2 = ['orange', 'lemon'];
console.log(arr1.concat(arr2)); // concat文
console.log([...arr1, ...arr2]); //　スプレッド構文
// 結果：["apple", "plum", "orange", "lemon"]
```

## 並び替え（reverse*, sort*）
### reverse*
配列の順番が反転します
非破壊的に並び替えをしたい場合（sortも同様）、スプレッド構文を使います

```sample.js
const arr = ['apple', 'plum', 'melon', 'orange'];
const arr2 = [...arr]; //スプレッド構文

console.log(arr.reverse());
// 結果： ["orange", "melon", "plum", "apple"]

console.log(arr2);
// 結果： ["apple", "plum", "melon", "orange"]
```

###sort*
下記コードでは文字列数を小さいものから大きいもの（昇順）にしています
`a < b`の場合（昇順）`0未満`、`a > b`の場合（降順）`0以上`をreturnします

```sample.js
const arr = ['apple', 'plum', 'orange'];
arr.sort((a, b) => {
  return a.length < b.length ? -1 : 1;
});
// 結果：["plum", "apple", "orange"]
```

## 探す（includes, indexOf, some, every）
### includes, indexOf
ES2016~の書き方で、要素自体を探すことができます
要素が見つかると０以上を返す`indexOf`よりも簡単に見つけ出せます

```sample.js
const arr = ['apple', 'plum', 'orange'];
console.log(arr.includes('orange'));
// 結果：true
```

### some, every
`some`は配列が条件を１つでも満たす場合、`every`は全て満たす場合に`true`を返します

```sample.js
const arr = ['fig', 'strawberry', 'plum'];
console.log(arr.some((value) => value.length > 9)); // 結果：true
console.log(arr.every((value) => value.length > 9)); // 結果：false
```

## 展開（forEach）
### forEach
要素をひとつずつ取り出すのに便利です
後述するmap, filter, reduceを使うと出番は少ないかもしれません

```sample.js
const arr = ['apple', 'plum', 'melon'];
arr.forEach((value) => {
  console.log(value);
});
/*結果
apple
plum
melon*/
```

## 加工（map, filter, reduce）
### map
配列内の各要素を順番に取り出して、**要素数分の結果**をつくることができます
第二引数にはindex（何番目の要素なのか）を指定することもできます

```sample.js
const arr = ['apple', 'plum', 'melon'];
let arr2 = [];

arr.map((val, index) => {
  arr2 = [...arr2, { id: index, name: val }];
});
console.log(arr2);

// 結果：[{id: 0, name: "apple"},{id: 1, name: "plum"},{id: 2, name: "melon"}]
```

### filter
配列内の各要素を順番に取り出して、**条件にあった数の結果**をつくることができます
下記では、フィルターしたい要素を否定演算子でfalseにしています

```sample.js
const arr = ['apple', 'plum', 'melon'];
console.log(arr.filter((val) => val !== 'plum'));
// 結果：["apple", "melon"]
```

### reduce
配列内の各要素を順番に取り出して、**１つの結果**を得ることができます
隣り合う2つの配列要素に対して左から右へ同時に関数を適用します
後ろにある`0`は初期値です


```sample.js
const arr = [{ price: 100, name: 'apple' }, { price: 110, name: 'plum' }, { price: 120, name: 'melon' }];
const total = arr.reduce((a, b) => a + b.price, 0);
console.log(total); // 結果：330
```

## 不変（freeze）
### freeze
値を一切変更させない(凍結)することができます

```sample.js
const obj = { id: 1, name: 'apple' };
obj.name = 'banana';
console.log(obj); // 結果：{id: 1, name: "banana"}

const obj2 = Object.freeze({ id: 2, name: 'orange' });
obj2.name = 'banana';
console.log(obj2); // 結果：エラー
```

##　まとめ
経験者なら「JavaScriptのfor文ってどんな書き方するんだろうー」と調べられるかもしれないですが、
わたしみたいなプログラミング初心者としては、どんなメソッドがあるのかはもちろん、
どんな方法をとって、自分の欲しいデータに成形すればいいのかが分かりません:fearful:

新しい書き方を含めたJavaScriptの配列操作一覧があったらいいなと思ってまとめましたが
自分にとって良い学習にもなりよかったです〜:blush: :heartbeat: 

上記以外にも便利な配列操作ご存知の方はぜひコメントいただけると嬉しいです！