重複を許さないリストを作るとき、リストを検索して存在しなければ追加するようなプログラムを書く事もあると思う。例えば、

 

List<int> nonDuplicateList

があったときに、

int data

を追加するとして

 

if(!nonDuplicateList.Exists(x => x == data))

    nonDuplicateList.Add(data)

 

のようにしたりとか。

 

データが数件の時には、これでも十分速さは出るものの、データが1000件を超えてくると、めちゃくちゃ遅くなる。毎度走査するから当然と言えば当然。

 

じゃあ高速だしHashを使えばいいじゃん、ということでDictionaryを使うと、今度はValueという要らないデータ領域が発生することになる。必要なデータはKeyであって、Valueはboolだろうとintだろうとなんでもよく、中身がnullであっても処理には関係しない。

 

そこで、System.Collection.Generic.HashSetを使う。ちなみにRubyだとSetとして用意されている。(require 'set'が必要)

 

C#

HashSet<int> set = new HashSet<int>();

 

Ruby

set = Set.new

 

としてやれば、あとは普通のリストと同じように使えば良い。

 

HashSetは集合を管理するクラスなので、重複はない。重複してAddしたところでデータは何も変わらない。なので、検索することなく適当にAddしていけば、勝手に重複のないリストを作り上げてくれる。また、IEnumerableを実装しているので、それ以外は基本的には通常のListと同じように扱えるので、至れり尽くせりである。

 

ただし、データ順序の保証は一切ないので、順序が重要ならば、最後にソートしてやる必要がある。

 

入れた順番とか、値以外の要素によって決まるならDictionaryのValueにでも順序を入れておき、最後にソートして取り出してやるとかしたら速いと思う。この場合だけは、DictionaryのValueが必要な領域となるため、こちらを使うと良いと思う。