ここでは、配列(またはコレクション)内に同じ要素が複数存在する時、これを1つだけにして、一意の要素のみの配列にする方法を紹介します。具体的に言えば、{ 1, 1, 2, 3, 1 }という配列から{ 1, 2 ,3 }という配列を作成するということです。
ここで紹介しているコードは配列を例にしていますが、コレクションでも同じようにできます。
まずは、最も基本的で、何の工夫もない方法から紹介します。
以下の例では、For文で配列内の要素を列挙して、新しく作成したコレクションにまだ存在しない要素だけを追加しています。
'基になる配列 Dim ary1 As Integer() = New Integer() {1, 1, 2, 3, 3, 1} '一意の要素を一時的に格納しておくコレクション '.NET Framework 2.0以降ならば、List(Of Integer)を使った方が良い Dim al As New System.Collections.ArrayList(ary1.Length) '基になる配列の要素を列挙する Dim i As Integer For Each i In ary1 'コレクション内に存在していなければ、追加する If Not al.Contains(i) Then al.Add(i) End If Next '配列に変換する Dim resultArray As Integer() = _ DirectCast(al.ToArray(GetType(Integer)), Integer()) 'resultArrayは{ 1, 2, 3 }となる
//基になる配列 int[] ary1 = new int[] { 1, 1, 2, 3, 3, 1 }; //一意の要素を一時的に格納しておくコレクション //.NET Framework 2.0以降ならば、List<int>を使った方が良い System.Collections.ArrayList al = new System.Collections.ArrayList(ary1.Length); //基になる配列の要素を列挙する foreach (int i in ary1) { //コレクション内に存在していなければ、追加する if (!al.Contains(i)) { al.Add(i); } } //配列に変換する int[] resultArray = (int[])al.ToArray(typeof(int)); //resultArrayは{ 1, 2, 3 }となる
また、ハッシュテーブルのキーが一意であることを利用して、次のようにすることもできます。
'基になる配列 Dim ary1 As Integer() = New Integer() {1, 1, 2, 3, 3, 1} '.NET Framework 2.0以降ならば、Dictionary(Of Integer, Integer)を使った方が良い '一意の要素を一時的に格納しておくハッシュテーブル Dim ht As New System.Collections.Hashtable(ary1.Length) '基になる配列の要素を列挙する For Each i As Integer In ary1 'ハッシュテーブルに追加する ht(i) = i Next '配列に変換する Dim resultArray As Integer() = New Integer(ht.Values.Count - 1) {} ht.Values.CopyTo(resultArray, 0)
//基になる配列 int[] ary1 = new int[] { 1, 1, 2, 3, 3, 1 }; //.NET Framework 2.0以降ならば、Dictionary<int, int>を使った方が良い //一意の要素を一時的に格納しておくハッシュテーブル System.Collections.Hashtable ht = new System.Collections.Hashtable(ary1.Length); //基になる配列の要素を列挙する foreach (int i in ary1) { //ハッシュテーブルに追加する ht[i] = i; } //配列に変換する int[] resultArray = new int[ht.Values.Count]; ht.Values.CopyTo(resultArray, 0);
.NET Framework 3.5から追加されたHashSetクラスは、要素の重複を許さないコレクションです。しかも、パフォーマンスが高いです。
以下の例では、HashSetを使って配列の要素を一意にしています。この例ではHashSetを一時的にしか使っていませんが、HashSetを普通のコレクションと同じように使用することもできます。
'基になる配列(コレクションでも可) Dim ary1 As Integer() = New Integer() {1, 1, 2, 3, 3, 1} 'HashSetに変換する Dim hs1 As New System.Collections.Generic.HashSet(Of Integer)(ary1) '配列に変換する Dim resultArray As Integer() = New Integer(hs1.Count - 1) {} hs1.CopyTo(resultArray, 0)
//基になる配列(コレクションでも可) int[] ary1 = new int[] { 1, 1, 2, 3, 3, 1 }; //HashSetに変換する System.Collections.Generic.HashSet<int> hs1 = new System.Collections.Generic.HashSet<int>(ary1); //配列に変換する int[] resultArray = new int[hs1.Count]; hs1.CopyTo(resultArray, 0);
.NET Framework 3.5以降でLinqを使えるのであれば、Enumerable.Distinctメソッドを使うと簡単です。
'Imports System.Linq '基になる配列(コレクションでも可) Dim ary1 As Integer() = New Integer() {1, 1, 2, 3, 3, 1} '一意の要素を抜き出して、配列に変換する Dim resultArray As Integer() = ary1.Distinct().ToArray()
//using System.Linq; //基になる配列(コレクションでも可) int[] ary1 = new int[] { 1, 1, 2, 3, 3, 1 }; //一意の要素を抜き出して、配列に変換する int[] resultArray = ary1.Distinct().ToArray();