フロントエンドでやることはだいたい配列の操作だと感じてます。
その中でも元の配列を非破壊に特定のインデックスの要素を配列から削除するのが意外と面倒でした
今まで方法
1. filter で削除する要素を取り除く
const result = array.filter((item) => item.id !== deleteID);
この方法は非破壊に要素を削除した配列を削除できるが、配列を全て捜査する分処理が無駄になる
2. 削除する index を探して slice で取り除く
const deleteIndex = array.findIndex((item) => item.id === deleteID); const result = [ ...array.slice(0, deleteIndex), ...array.slice(deleteIndex + 1) ];
削除する要素の index を見つけるまで配列を捜査して、slice
で配列から削除する要素を除いた配列を作成する方法
slice
で index の要素を削除した配列を作成するコードが若干見通しが悪い
3. 配列を先にコピーして splice で要素を削除する
const deleteIndex = array.findIndex((item) => item.id === deleteID); const copyArray = […array]; // or const Array = structuredClone(array); (deep copy) copyArray.splice(deleteIndex, 1); const result = copyArray;
.splice(deleteIndex, 1)
で特定の index の要素を削除できるが、splice()
は元の配列を変更してしまう破壊メソッドなので、先に配列を スプレッド構文 (Shallow copy) か structuredClone
(Deep copy) コピーしておく必要がある
toSpliced()
メソッド
toSpliced()
は Array インスタンスのメソッドで、splice()
メソッドに対応するコピーメソッドです。これは、指定された位置の要素を除去したり置き換えたりした新しい配列を返します。
cf. Array.prototype.toSpliced() - JavaScript | MDN
toSpliced()
メソッドは splice()
メソッドでできる配列の要素の削除・追加・置き換えを非破壊的にでき、新しい配列を返してくれる
const deleteIndex = array.findIndex((item) => item.id === deleteID); const result = array.toSpliced(deleteIndex, 1);
従来の方法の 2, 3 を合わせてシンプルにしたように書ける!
Tips toSpliced()
と splice()
の挙動の違い
splice()
を使うことはあまりないと思いますが、破壊/非破壊だけでなく返り値に違いがあるので注意が必要です
toSpliced()
は元の配列を変化させない (非破壊)・新しい配列を返すsplice()
は元の配列を変化させる (破壊)・削除した要素の配列を返す
Sample
要素の削除
// toSpliced const a1 = [1, 2, 3, 4, 5]; const res1 = a1.toSpliced(1, 2); console.log(a1); // [1, 2, 3, 4, 5] console.log(res1); // [1, 4, 5] // splice const a2 = [1, 2, 3, 4, 5]; const res2 = a2.splice(1, 2); console.log(a2); // [1, 4, 5] console.log(res2); // [2, 3]
要素を削除して追加
// toSpliced const a1 = [1, 2, 3, 4, 5]; const res1 = a1.toSpliced(1, 2, 'a', 'b', 'c'); console.log(a1); // [1, 2, 3, 4, 5] console.log(res1); // [1, 'a', 'b', 'c', 4, 5] // splice const a2 = [1, 2, 3, 4, 5]; const res2 = a1.splice(1, 2, 'a', 'b', 'c'); console.log(a2); // [1, 'a', 'b', 'c', 4, 5] console.log(res2); // [2, 3]
これからは配列からの要素の削除は toSpliced()
を使って見通しよく書いていけそうで嬉しいです!
配列からの削除めんどいなと思って調べなかったら気づくこと無く slice
や filter
で書いているところでした… ES2022, ES2023 で配列の非破壊メソッドが結構追加されているようなので、サボらずちゃんとキャッチアップしようと思ったのでした
おわり₍ᐢ. ̫.ᐢ₎
[参考]
- Array.prototype.toSpliced() - JavaScript | MDN
- JavaScriptのES2023・ES2022の新機能まとめ - ICS MEDIA
- 【JavaScript】ES2023で導入された非破壊的メソッド #JavaScript - Qiita
- [TypeScript]配列(array)の要素をインデックス指定で削除する(remove element at index)には? | ちょげぶろぐ
- Array.prototype.splice() - JavaScript | MDN
- Array.prototype.slice() - JavaScript | MDN
- structuredClone() - Web API | MDN