DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

配列(またはコレクション)の重複する要素を削除して、一意にする

ここでは、配列(またはコレクション)内に同じ要素が複数存在する時、これを1つだけにして、一意の要素のみの配列にする方法を紹介します。具体的に言えば、{ 1, 1, 2, 3, 1 }という配列から{ 1, 2 ,3 }という配列を作成するということです。

ここで紹介しているコードは配列を例にしていますが、コレクションでも同じようにできます。

For文を使用する方法

まずは、最も基本的で、何の工夫もない方法から紹介します。

以下の例では、For文で配列内の要素を列挙して、新しく作成したコレクションにまだ存在しない要素だけを追加しています。

VB.NET
コードを隠すコードを選択
'基になる配列
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 }となる
C#
コードを隠すコードを選択
//基になる配列
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 }となる

また、ハッシュテーブルのキーが一意であることを利用して、次のようにすることもできます。

VB.NET
コードを隠すコードを選択
'基になる配列
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)
C#
コードを隠すコードを選択
//基になる配列
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);

HashSetクラスを使用する方法

.NET Framework 3.5から追加されたHashSetクラスは、要素の重複を許さないコレクションです。しかも、パフォーマンスが高いです。

以下の例では、HashSetを使って配列の要素を一意にしています。この例ではHashSetを一時的にしか使っていませんが、HashSetを普通のコレクションと同じように使用することもできます。

VB.NET
コードを隠すコードを選択
'基になる配列(コレクションでも可)
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)
C#
コードを隠すコードを選択
//基になる配列(コレクションでも可)
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);

Enumerable.Distinctメソッドを使用する方法

.NET Framework 3.5以降でLinqを使えるのであれば、Enumerable.Distinctメソッドを使うと簡単です。

VB.NET
コードを隠すコードを選択
'Imports System.Linq

'基になる配列(コレクションでも可)
Dim ary1 As Integer() = New Integer() {1, 1, 2, 3, 3, 1}

'一意の要素を抜き出して、配列に変換する
Dim resultArray As Integer() = ary1.Distinct().ToArray()
C#
コードを隠すコードを選択
//using System.Linq;

//基になる配列(コレクションでも可)
int[] ary1 = new int[] { 1, 1, 2, 3, 3, 1 };

//一意の要素を抜き出して、配列に変換する
int[] resultArray = ary1.Distinct().ToArray();

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。