2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScript:その配列内検索、ArrayよりSetの方がいいかも?

Last updated at Posted at 2024-01-27

はじめに

JavaScriptでまとまったデータを管理する際、Array(配列)を使用することも多いと思いますが、特定のケースではSetというオブジェクトの方が優れているよ、というお話です。この記事では、SetとArrayの違いと、それぞれの使用場面について解説します。

本題

この記事では下記を解説していきます。

  • Setってそもそも何?
  • ArrayよりもSetの方が優れている点

Setってそもそも何?

SetはJavaScriptの組み込みオブジェクトで、重複を許さない値の集合を管理するために使用されます。Arrayと違ってSetには重複した値は格納できないということです。
Setの基本的な使い方はこんな感じです。

const uniqueNumbers = new Set([1, 2, 3, 2, 1]);
console.log(uniqueNumbers); // Set(3) {1, 2, 3}

/* 重複した 2 と 1 は格納されない。*/

ArrayよりもSetの方が優れている点

先ほどのSetの基本的な使い方を踏まえ、ArrayよりSetを使った方が良い場面を考えていきましょう。

ループ処理での重複排除

例えば、イベントAまたはイベントBのどちらかに参加しているユーザーを算出したいとき、重複削除が役に立ちます。

// 2つの異なるAPIから取得されたイベント参加ユーザーIDのリスト
const eventA_user = [101, 102, 120, 190, 200];
const eventB_user = [101, 102, 350, 356, 407];

// Setを使用して重複を排除
const uniqueUserIds = new Set([...eventA_user, ...eventB_user]);
console.log(uniqueUserIds); 
// 出力: Set(8) {101, 102, 120, 190, 200, 350, 356, 407}

重複した値を入れないと明示できる

Setは重複した値を格納することができないので、コードを見た人が「ああ、これは一意の値を扱っているから同じ値を入れないようにしているんだな」とすぐに理解することができます。

配列内の検索パフォーマンスが高い

僕が今回推したい点はここです。
大量のデータが入った配列に特定の値が存在するかどうかを効率的に調べたい場合はSetの方が良いです。
例として該当のuserIdを見つけるための比較をArrayとSetの両方で見てみましょう。

//調べたいID
const targetUserId = 308; 
//検索する箱
const allUserId = [2,10,34,50,66,78,・・・,308・・・続く]

// Arrayの場合・・・findメソッドを使用
const result = allUserId.find(id => id === targetUserId);
console.log(result) // 出力: 308

// Setの場合・・・hasメソッドを使用
const set = new Set(allUserId);
const result2 = set.has(308);
console.log(result2) // 出力: true

上記を見ると結果の値が少し違いますね。
Arrayでfindを使った場合は配列から該当の値を返しています。また、Setでhasを使った場合はBoolean型で返ってきています。
※hasメソッドは引数に入っている値が検索対象に存在するかどうかをみています。

え?むしろSetの方が1行長くなるしArrayでよくない?
そうですよね。僕も最初はそう思いました。
でも、検索の効率性が違います。

findメソッドは対象の配列を順番に見ていきます。つまり下記コードではallUserIdの中を、[1]の値は308じゃないじゃないから次、[2]の値は308じゃないから次、[3]の値は308じゃないから次、という感じで順々に見ているのです。そして無事308へ辿り着いたときにその値を返してくれます。

const targetUserId = 308; 
const allUserId = [2,10,34,50,66,78,・・・,308・・・続く]
const result = allUserId.find(id => id === targetUserId);

対してhasメソッドは、、
308を超高速で見つけてくれます。

これはArrayのようにデータを要素番号と値のペアで管理しているのではなく、「ハッシュテーブル」というデータ構造で管理しているためです。これによってデータ量に関わらず検索したい値を直接確認できるのです!!

ハッシュテーブルについては下記がわかりやすいです。

この違いは検索パフォーマンスにおいて雲泥の差になります。検索対象のデータ数が10個とかならそんなに変わりませんがデータが増えれば増えるほどSetのhasメソッドが有利になりますね。
ただし、SetはArrayと違って要素に順番にアクセスする機能が限られています!特定の状況に応じて、ArrayとSetを適切に使い分けることができればグッドですね🙆‍♂️

まとめ

ここまでの流れを振り返ってArrayとSetの使い分をまとめておきます。

Arrayの使用シナリオ
・順序が重要な場合
・重複した値の保持が必要な場合

Setの使用シナリオ
重複を許さない値の管理が必要な場合
大量のデータからの高速な検索が必要な場合

読んでいただきありがとうございました。
何かお気づきの点等あれば教えていただけると嬉しいです🙇‍♂️

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?