【JavaScript】混同しがち splice、split、sliceの違いと使い方

## splice、split、slice　単語が似てるので...
splice、split、sliceって単語が似ていて、たまにしか使わないからどれだっけ？
ってなりますよね :sweat_smile:
ということで、違いと使い方を備忘録として記載してみました。参考の程 :wink:

## これだけは意識しよう!!　<font color="red">splice</font>は<font color="red">要注意!!</font>
| メソッド名 | 破壊的メソッド | 何を | 何で返す |
|:-----------|:------------:|:------------:|:------------:|
|<font color="red">**splice**</font>| <font color="red">**○**</font> |**配列**| （取り除かれた要素を含む）**配列**|
|split| × |文字列|（分割した文字列を要素に持つ）配列
|slice| × |配列 /　文字列 | 配列 / 文字列

**破壊的メソッド**・・・元のデータ構造を変更するメソッドの事

## こんな意味
| メソッド名 | 英語を和訳　|
|:-----------|:------------:|
|splice|つなぎ合わせる、結合する、接合部
|split|裂く、割る、分ける、分裂
|slice|薄く切る、薄片、一切れ、部分

## spliceの使い方
:::note
**splice**
**配列.splice(start, deleteCount, item1, item2, ..., itemN)**
:::
* **start（必須）**: 操作を開始する要素のインデックス
* **deleteCount（省略可）**: 削除する要素の数（取り出す要素の数）  
省略すると、startから最後まで
* **itemN（省略可）**: 追加する要素。省略すると、削除のみ実行

:diamonds:spliceを使う時の注目キーワード:diamonds:

:writing_hand: 破壊的 :writing_hand: 追加 :writing_hand: 削除 :writing_hand: 置換 :writing_hand: 結合 :writing_hand: スプレッド構文 :writing_hand: 分割
```js:spliceの例（削除）
const fruits = ['apple', 'banana', 'cherry'];
const result = fruits.splice(1, 1); //（開始のインデックス,取り出す個数）

console.log(fruits); // ['apple', 'cherry'] 元の配列が変わる
console.log(result); // ['banana'] 取り出された要素が入る
```

```js:spliceの例（追加）
const fruits = ['apple', 'banana'];
const result = fruits.splice(1, 0, 'cherry'); //（開始のインデックス,取り出す個数,要素）

console.log(fruits); // ['apple', 'cherry', 'banana'] 元の配列が変わる
console.log(result); // [] 何も取り出されていないので空
```
```js:spliceの例（置換）
const fruits = ['apple', 'banana', 'cherry'];
const result = fruits.splice(1, 1, 'orange'); //（開始のインデックス,取り出す個数,要素）

console.log(fruits); // ['apple', 'orange', 'cherry']　元の配列が変わる
console.log(result); // ['banana'] 取り出された要素が入る
```
spliceは取り出してつなげるので、**スプレッド構文**を使う事で結合する事ができる


```js:spliceの例（結合）
const a = [10, 20];
const b = [30, 40];
a.splice(a.length, 0, ...b);

console.log(a); // [10, 20, 30, 40]
```
**第1引数のみの場合**、start位置より後は削除、元配列と処理後の配列が**分割**する様な形になる

```js:spliceの例（削除 / 分割）
const alphabet = ['a', 'b', 'c', 'd', 'e'];
const result = alphabet.splice(2); //（開始のインデックス）

console.log(alphabet); // ['a', 'b', 'c'] 元の配列が変わる
console.log(result); // ['d', 'e'] 取り出された要素が入る
```

:::note warn
**splice**を使うと、**元の配列が変わってしまう**ので、**元の配列をコピー**しておくことで、元の配列が変更されることを防ぎ、安全に操作を行うことができる。

:::
```javascript:コピーの例
const arr = [1, 2, 3];
const copyArr = [...arr];  // スプレッド構文
```


## splitの使い方
:::note
**split**
**文字列.split(separator, limit)**
:::
* **separator（省略可）**: 分割の基準となる文字列（例: カンマやスペース）
* **limit（省略可）**: 最大で返される配列の要素数。省略すると、文字列全体が指定した区切り文字で分割され、全ての部分が配列として返される

:diamonds:splitを使う時のキーワード:diamonds:
:writing_hand: 文字列を分割　:writing_hand: 区切り文字（例えばcsv形式）:writing_hand: 正規表現　:writing_hand: 分割個数

```js:splitの例
const str = "apple,banana,cherry";
const arr2 = str.split(",");

console.log(arr2);// ["apple", "banana", "cherry"]
```
```js:splitの例（特定の文字で分割）
const sentence = "Hello world!";
const words = sentence.split(" "); 

console.log(words); // ["Hello", "world!"]
```
```js:splitの例（特定の文字で分割）
const data = "one|two|three";
const items = data.split("|");

console.log(items); // ["one", "two", "three"]
```
```js:splitの例（限度設定）
// limit引数で、返される配列の要素数を制限
const text = "a,b,c,d,e";
const limited = text.split(",", 3);

console.log(limited); // ["a", "b", "c"]
```
```js:splitの例（正規表現）
const text = "one1two2three";
const parts = text.split(/\d/); // 0から9までのいずれかでマッチした数字で分割

console.log(parts); // ["one", "two", "three"]
```
```js:splitの例(１文字ずつの配列を作成)
const text = "abc";
const result = text.split('');

console.log(result); // ["a",　"b",　"c"]
```
```js:splitの例(文字列が空の場合)
const emptyString = "";

// 文字列は空で、セパレーターは空ではない
console.log(emptyString.split("a")); // [""] 空文字列を1つ含む配列　

// 文字列とセパレーターがともに空文字列
console.log(emptyString.split(emptyString)); // []
```
引数を指定しない場合やundefinedの場合、元の文字列が1つの要素として返される

```js:splitの例（separator を省略したり undefined を渡したりすると）
const text = "hello world";
const result = text.split();
console.log(result); // ["hello world"]

const result2 = text.split(undefined); 
console.log(result2); // ["hello world"]
```

## sliceの使い方
:::note
**slice**
**slice(start, end)**
splitと似ているが、<font color="red">文字列で返したいならsliceを使う</color>

:::

* **start（省略可）**: 操作を開始する要素のインデックス
* **end（省略可）**:endのインデックス自身は**含まない。**、省略すると、startから末尾まで指定される


**sliceを使う時の注目キーワード**

:writing_hand: 配列と文字列 :writing_hand: endのインデックスは含まない :writing_hand: 配列のコピー :writing_hand: 負のインデックス

```javascript: sliceの例（配列と文字列）
// 配列の一部を返す
const arr = [1, 2, 3, 4, 5];
const newArr = arr.slice(1, 3);
console.log(newArr); // [2, 3]

// 文字列の一部を返す
const str = "Hello, World!";
const newStr = str.slice(7, 12);
console.log(newStr);  // "World"
// 注意）スペースはインデックスに含む、endのインデックスは含まない
```

```javascript: sliceの例（配列のコピー）
// 引数を空に指定した場合、配列のコピーを作る事ができる
const arr = [1, 2, 3];
const copyArr = arr.slice();

console.log(arr); // [1, 2, 3]
console.log(copyArr); // [1, 2, 3]
```

```javascript: sliceの例（負のインデックス）
// 負のインデックスで配列や文字列の末尾からの要素を取得
const arr = [1, 2, 3, 4, 5];
const lastTwo = arr.slice(-2);
const last = arr.slice(2, -1); //(endのインデックスは含まない)

console.log(lastTwo); // [4, 5]
console.log(last); //[3, 4]
```



## おまけ　「疎配列」（Sparse Arrays）とは

:::note
**疎配列**
「空（empty）」 の「要素（スロット、slot）」を1つ以上持つ配列のこと
配列の要素の値として undefined でも null でもない概念「空（**empty**）」がある
:::
```javascript:例
// 密な配列
let arr = [1,2,3];
// 疎な配列
let arr1 = [ ,2,3];
// 疎な配列
let arr2 = new Array(3); //[ <3 empty items> ] または [ , , , ]
```
疎配列では、配列の要素数とlengthプロパティの値は一致しない
```javascript:例
// 疎な配列  要素数2
let arr1 = [ ,2,3];
console.log(arr1.length);    // 3
```

| メソッド名 | 疎配列の扱い |
|:-----------|:------------:|
|splice | 扱える |
|split| 文字列操作のため、無関係 |
|slice| 扱える |

```javascript:疎配列 / splice例
const arr = [1, , 3, 4, , 6];
console.log(arr.splice(1, 2)); // [empty, 3]
console.log(arr); // [1, 4, empty, 6]
```
```javascript: 疎配列 /sliceの例
const arr = [1, , 3];
const newArr = arr.slice(0, 3);
console.log(newArr); // [1, empty, 3]
```

## 参考
[【JavaScript】 spliceメソッドについて徹底解説！ | Pikawaka](https://pikawaka.com/javascript/splice)

[Array.prototype.splice() - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)


[<title>String.prototype.split() - JavaScript | MDN</title>](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split)

[Array.prototype.slice() - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)