JavaScriptの配列の重複を削除するテクニック(Set・filter活用)
生徒
「JavaScriptで配列の中に同じ値が何回も入っている時、それを一つだけにまとめる方法ってありますか?」
先生
「はい、重複した値を取り除く方法は2つよく使われます。ひとつはSetという特別なデータ構造を使う方法、もうひとつはfilterメソッドを使う方法です。」
生徒
「Setって何ですか?filterは聞いたことありますが、どうやって使うんですか?」
先生
「順を追って説明していきますね。」
1. 配列の重複とは?
配列とは、複数のデータを順番にまとめて管理できる便利な仕組みですが、処理の流れやデータの集め方によっては、同じ値が何度も入ってしまうことがあります。これを「配列の重複」と呼びます。
たとえば、ユーザーが選択した項目を配列に追加していく場合や、検索結果をまとめる処理などでは、気づかないうちに同じデータが重なってしまうことがよくあります。見た目は問題なさそうでも、あとから処理を行う際に思わぬ不具合につながることがあります。
次の例は、果物の名前を配列に入れたシンプルなサンプルです。一見すると普通の配列ですが、同じ「りんご」が複数回入っています。
let fruits = ["りんご", "みかん", "りんご", "バナナ"];
console.log(fruits);
このように、同じ値が配列の中に何度も含まれている状態を整理して、一つずつにまとめる処理を「重複の削除」と言います。JavaScriptでは、この重複削除を行うための便利な方法が用意されており、初心者の方でも比較的簡単に扱えるのが特徴です。
2. Set(セット)を使った重複削除
Setは、JavaScriptに用意されている「同じ値を二つ以上入れられない特別な入れ物」です。つまり、配列の中身をいったんSetに入れるだけで、重複している値が自動的に整理されて、一つずつにまとまります。
たとえば、同じ商品名やタグ、ユーザーが選んだ項目などを配列で集めていると、知らないうちに同じ値が混ざることがあります。そんなときSetを使うと、「重複しているかを自分でチェックする処理」を書かなくても済むので、初心者でも読みやすいコードになりやすいです。
let fruits = ["りんご", "みかん", "りんご", "バナナ"];
let uniqueFruits = [...new Set(fruits)];
console.log(uniqueFruits); // ["りんご", "みかん", "バナナ"]
ここで使ったnew Set(fruits)が「重複をまとめる部分」です。Setの中では同じ値が一つだけになるので、結果として重複が消えます。
そして、[... ]は「Setを配列に戻すための書き方」です。Setのままでも使える場面はありますが、配列として扱いたいことが多いので、最後に配列へ戻すのが定番です。
let numbers = [1, 2, 2, 3, 1];
let uniqueNumbers = [...new Set(numbers)];
console.log(uniqueNumbers); // [1, 2, 3]
このように、文字列でも数値でも同じ手順で重複削除ができます。まずは「配列をSetに入れて、配列に戻す」と覚えておくと、配列の整理がぐっと楽になります。
3. filterメソッドを使った重複削除
filterは、配列の中から「条件に合うものだけ」を取り出して、新しい配列を作るメソッドです。これを重複削除に使うときは、「同じ値が最初に出てきたときだけ残す」というルールにします。言い換えると、二回目以降に出てきた同じ値は、条件に合わないので落とされる仕組みです。
やり方のポイントは、indexOfで「その値が最初に出てくる場所」を調べ、いま見ている位置(index)と一致しているかを比べることです。一致していれば初登場なので残し、一致していなければ重複なので削除されます。
let fruits = ["りんご", "みかん", "りんご", "バナナ"];
let uniqueFruits = fruits.filter((item, index) => {
return fruits.indexOf(item) === index;
});
console.log(uniqueFruits); // ["りんご", "みかん", "バナナ"]
ここでindexOfは「配列の中で最初にその値が出てくる場所(番号)」を返します。filterは左から順番に見ていくので、最初の「りんご」は残り、二回目の「りんご」は最初の場所とズレるため削除されます。
もう少し身近な例として、買い物リストを考えてみましょう。同じ商品名を何度もメモしてしまったときでも、filterなら「最初に書いた一回だけ残す」という形で整理できます。
let shopping = ["牛乳", "卵", "牛乳", "パン", "卵"];
let uniqueShopping = shopping.filter((item, index) => {
return shopping.indexOf(item) === index;
});
console.log(uniqueShopping); // ["牛乳", "卵", "パン"]
Setより少し長く書く必要はありますが、filterは「条件を変えたい」ときに強い方法です。たとえば文字の大文字小文字をそろえてから判定したい、前後の空白を除いてから判定したい、といった場面でも考え方を応用しやすいのが特徴です。
4. Setとfilterの違いと使い分け
どちらも重複削除には使えますが、Setの方が簡単で処理も速いことが多いです。ただし、filterは「条件を変えたい」「少し複雑な判定をしたい」ときに便利です。
例えば、オブジェクトの配列で重複を判定したい場合はfilterの方が柔軟に対応できます。
5. オブジェクト配列の重複削除はfilterで
オブジェクトの配列で、特定のキー(例えばID)が重複しているかで重複削除したい場合は次のようにします。
let people = [
{id: 1, name: "太郎"},
{id: 2, name: "花子"},
{id: 1, name: "太郎"}
];
let uniquePeople = people.filter((person, index, self) =>
index === self.findIndex((p) => p.id === person.id)
);
console.log(uniquePeople);
/* 出力
[
{id: 1, name: "太郎"},
{id: 2, name: "花子"}
]
*/
ここではfindIndexで「同じIDの最初の場所」を調べて、その位置と今の位置が同じなら残す、違うなら重複とみなして削除しています。
6. 数値配列の重複削除で気をつけたいポイント
文字列の配列だけでなく、数値の配列でも重複削除はよく行われます。例えば、点数やID番号、カウント結果などを配列で扱っていると、同じ数値が何度も入ってしまうことがあります。このような場合も、基本的な考え方はこれまでと同じです。
Setを使えば数値の重複も自動で取り除かれますが、型の違いには注意が必要です。数値の1と文字列の"1"は別の値として扱われるため、意図しない結果にならないよう、配列の中身をそろえておくことが大切です。
let numbers = [1, 2, 3, 2, 1, 4];
let uniqueNumbers = [...new Set(numbers)];
console.log(uniqueNumbers); // [1, 2, 3, 4]
数値配列の場合は処理がシンプルなことが多いため、まずはSetで対応できないかを考えると、コードがすっきりまとまりやすくなります。
7. 配列の順番はそのまま保たれるのか?
重複削除を行う際に気になるポイントのひとつが、「元の配列の順番がどうなるか」という点です。結論から言うと、今回紹介しているSetとfilterの方法では、どちらも元の配列の順番を保ったまま重複が削除されます。
Setは、最初に登場した順番で値を保持する仕組みになっています。そのため、配列をSetに変換しても、並び順が勝手に変わることはありません。
let fruits = ["バナナ", "りんご", "みかん", "りんご"];
let uniqueFruits = [...new Set(fruits)];
console.log(uniqueFruits); // ["バナナ", "りんご", "みかん"]
表示順や処理順が重要な場面でも安心して使える点は、配列の重複削除を行ううえで大きなメリットと言えるでしょう。
8. どの方法を選ぶか迷ったときの考え方
配列の重複削除にはいくつか方法がありますが、すべてを完璧に使い分ける必要はありません。まずは「配列の中身が何か」を確認し、「単純な値か」「オブジェクトか」という視点で考えるのがおすすめです。
文字列や数値の配列であればSet、オブジェクト配列や条件付きの重複判定が必要な場合はfilter、というように大まかに覚えておくだけでも、実務では十分に役立ちます。
大切なのは、コードを無理に複雑にしないことです。あとから見返したときに「何をしている処理なのか」がすぐ分かる書き方を選ぶことで、保守性の高いJavaScriptコードにつながります。重複削除はその良い練習題材になるので、ぜひいろいろな配列で試してみてください。
まとめ
配列の重複削除で身につけたい基本の考え方
この記事では、JavaScriptで配列の重複を削除する代表的な方法として、Setとfilterを使ったテクニックを学んできました。
配列はとても便利なデータ構造ですが、実際の開発では同じ値が何度も入ってしまうことがよくあります。
そのまま処理を続けてしまうと、画面に同じデータが何度も表示されたり、集計結果がずれてしまったりと、思わぬ不具合につながります。
そのため、「配列の重複を削除する」という考え方は、JavaScriptの基礎でありながら、実務でも頻繁に使われる重要な知識です。
Setを使う方法は、とにかくシンプルで直感的です。
「同じ値は一つしか入らない箱に入れ替える」という発想は、プログラミング未経験の方でも理解しやすく、短いコードで配列の重複削除を実現できます。
一方で、filterを使った方法は少し考え方が必要ですが、「最初に出てきた要素だけを残す」というロジックを理解すると、条件を自由にカスタマイズできる強みがあります。
Setとfilterの使い分けを整理しよう
単純な文字列や数値の配列であれば、Setを使う方法が最も手軽です。
コードも短く、読みやすいため、配列の重複削除をしたい場面ではまず最初に思い浮かべたい方法です。
反対に、オブジェクトの配列や、「この条件が同じなら重複とみなす」といった細かいルールが必要な場合には、filterが活躍します。
特にIDやキーを基準に重複を削除したい場合は、findIndexと組み合わせることで柔軟な処理が可能になります。
次のサンプルは、実務でもよくある「IDが重複していないデータだけを残す」処理の考え方を、もう一度シンプルに整理したものです。
let items = [
{ id: 1, name: "商品A" },
{ id: 2, name: "商品B" },
{ id: 1, name: "商品A" }
];
let uniqueItems = items.filter((item, index, self) => {
return index === self.findIndex(i => i.id === item.id);
});
console.log(uniqueItems);
このように、重複削除のロジックを一度理解してしまえば、配列の種類が変わっても応用できるようになります。 JavaScriptの配列操作に慣れてくると、「この配列はSetでいけそうか」「filterで条件を作った方がよさそうか」と自然に判断できるようになってきます。
配列操作に慣れるためのコツ
配列の重複削除は、mapやfilter、findIndexなど、JavaScriptの配列メソッドを理解する良い練習になります。 最初はコードの意味を一行ずつ追いながら、「なぜこの条件で重複が消えるのか」を意識して読むことが大切です。 ただ結果を覚えるのではなく、「配列を上から順番に見ている」「最初に出てきたものだけを残している」といった流れをイメージできるようになると、理解が一気に深まります。
生徒
「配列の重複削除って難しそうだと思っていましたが、Setを使う方法は意外とシンプルでした」
先生
「そうですね。まずはSetで簡単に書けるケースを覚えるのが大切です」
生徒
「でも、オブジェクト配列になるとfilterの方が便利なんですね」
先生
「その通りです。条件を自由に決められるのがfilterの強みです」
生徒
「これからは、配列の中身を見て、どの方法が合っているか考えてみます」
先生
「その意識があれば、JavaScriptの配列操作はどんどん得意になりますよ」