slice() は、配列の一部を新しい配列にして返します。元の配列は変わりません。
splice() は名前が似ていますが、元の配列を書き換えます。
戻り値は同じでも、fruits が変わっています。
文字が1つ違うだけで、まったく別のものです。
slice() |
splice() |
|
|---|---|---|
| 元の配列 | 変わらない | 書き換わる |
| 第2引数 | 終わりの位置 | 取り除く個数 |
| 戻り値 | 取り出した部分 | 取り除いた部分 |
| 要素を足す | できない | できる |
slice(start, end)
第2引数は終わりの位置で、そこは含みません。
- 省略すると最後まで
- 負の数は後ろから数えます
- 引数なしは全部の複製
startがendより後ろなら空配列。入れ替えてはくれません
考え方は文字列の slice()と同じです。
複製は「浅い」
slice() が作るのは新しい配列ですが、中身は同じものを指しています。
配列そのものは別(false)でも、中のオブジェクトは同じ(true)です。
これを浅いコピーと呼びます。
複製したつもりで元が変わるのは、ここが原因であることがほとんどです。
splice(start, 削除数, 足すもの...)
第2引数は取り除く個数です。位置ではありません。
const fruits = ['あ', 'い', 'う', 'え', 'お'];
console.log(fruits.splice(1, 3));削除数を0にすると、取り除かずに差し込むだけになります。 何も取り除いていないので、戻り値は空配列です。
置き換えもできます。
const fruits = ['あ', 'い', 'う'];
const rest = fruits.splice(0, 1);
console.log(rest);const nums = [1, 2, 2, 3];
for (let i = 0; i < nums.length; i++) {
if (nums[i] === 2) nums.splice(i, 1);
}
console.log(nums);削除数を省くと、そこから後ろが全部消えます。
開始位置には負の数も使えます。
元を変えたくないなら toSpliced()
splice() と同じことを、元を変えずにします(ES2023)。
Node 20 / Chrome 110 / Safari 16 より前の環境では使えません。
よくある間違い
splice() の第2引数を位置だと思う
1番目から3番目まで、のつもりが3個取り除かれています。
slice(1, 3) なら2個です。同じ数字を渡しても結果が違います。
splice() の戻り値を「残り」だと思う
返るのは取り除いたほうです。残りは元の配列(fruits)に入っています。
繰り返しの中で splice() する
2 が1つ残りました。
取り除くと後ろが前に詰まるのに、i は進んでしまうので1つ飛ばして見ています。
filter() を使えば、この問題は起きません。
取り除きたいときは、まず filter() を考えてください。
→ 配列を変換する・絞り込む
まとめ
slice()は取り出すだけ。元は変わらないsplice()は元を書き換える。第2引数は個数slice()の複製は浅いコピー。中のオブジェクトは共有されるsplice(i, 0, x)で差し込み、splice(i, 1, x)で置き換え- 元を変えたくないなら
toSpliced() - 繰り返しの中で
splice()しない。filter()を使う