C#
 Computer >> コンピューター >  >> プログラミング >> C#

C#のSortedSetとコレクションの積集合を求める方法(IntersectWithメソッド)

C#のSortedSet<T>クラスには、現在のセットと指定したコレクションの共通要素(積集合)だけを残すためのIntersectWith()メソッドが用意されています。このメソッドを呼び出すと、引数で渡したコレクションにも存在する要素のみがセット内に保持され、それ以外の要素はすべて削除されます。

ここでは、IntersectWith()メソッドを使ってSortedSetと別のコレクションの交差(積集合)を求める方法を、具体的なコード例とともに解説します。

例1:整数型のSortedSet同士の積集合

まずはint型のSortedSetを2つ作成し、一方に他方との共通要素だけを残す基本的な例です。

using System;
using System.Collections.Generic;
public class Demo {
    public static void Main(){
        SortedSet<int> set1 = new SortedSet<int>();
        set1.Add(100);
        set1.Add(200);
        set1.Add(300);
        SortedSet<int> set2 = new SortedSet<int>();
        set2.Add(450);
        set2.Add(200);
        set2.Add(650);
        set2.Add(300);
        set2.Add(800);
        Console.WriteLine("同じ要素を持っているか? = " + set1.SetEquals(set2));
        set1.IntersectWith(set2);
        Console.WriteLine("演算後のSortedSet...");
        foreach(int val in set1){
            Console.WriteLine(val);
        }
    }
}

実行結果

同じ要素を持っているか? = False
演算後のSortedSet...
200
300

解説

まずSetEquals()メソッドで両セットが同一の要素を持つかどうかを確認しています。set1とset2は共通する要素(200と300)を持ちますが、内容は完全には一致しないため「False」が出力されます。

その後、set1.IntersectWith(set2)を実行すると、set1にはset2にも存在する要素である200と300だけが残ります。SortedSetは常にソートされた状態を保つため、結果も昇順で表示される点に注目してください。

例2:文字列型のSortedSetとEnumeratorを使った積集合

次に、string型のSortedSetを使用し、Enumerator(列挙子)で要素を走査する例を見てみましょう。

using System;
using System.Collections.Generic;
public class Demo {
    public static void Main(){
        SortedSet<string> set1 = new SortedSet<string>();
        set1.Add("AB");
        set1.Add("BC");
        set1.Add("CD");
        set1.Add("EF");
        set1.Add("PQ");
        set1.Add("ST");
        Console.WriteLine("SortedSet1の要素...");
        foreach (string res in set1){
            Console.WriteLine(res);
        }
        Console.WriteLine("SortedSet1の要素数 = " + set1.Count);
        SortedSet<string> set2 = new SortedSet<string>();
        set2.Add("BC");
        set2.Add("CD");
        set2.Add("DE");
        set2.Add("EF");
        set2.Add("AB");
        set2.Add("HI");
        set2.Add("JK");
        Console.WriteLine("SortedSet2の要素(Enumeratorで走査)...");
        SortedSet<string>.Enumerator demoEnum = set2.GetEnumerator();
        while (demoEnum.MoveNext()) {
            string res = demoEnum.Current;
            Console.WriteLine(res);
        }
        Console.WriteLine("SortedSet2の要素数 = " + set2.Count);
        set1.IntersectWith(set2);
        Console.WriteLine("演算後のSortedSet...");
        foreach(string val in set1){
            Console.WriteLine(val);
        }
    }
}

実行結果

SortedSet1の要素...
AB
BC
CD
EF
PQ
ST
SortedSet1の要素数 = 6
SortedSet2の要素(Enumeratorで走査)...
AB
BC
CD
DE
EF
HI
JK
SortedSet2の要素数 = 7
演算後のSortedSet...
AB
BC
CD
EF

解説

set1には6個、set2には7個の文字列要素が格納されています。set2の要素はGetEnumerator()で取得した列挙子をMoveNext()Currentを使って1件ずつ取り出して表示しています。

IntersectWith(set2)を実行した後、set1には両方のセットに共通して存在する「AB」「BC」「CD」「EF」の4要素のみが残ります。「PQ」と「ST」はset2に存在しないため削除されました。

まとめ

  • IntersectWith()メソッドは、呼び出し元のSortedSetを直接変更(破壊的操作)します。元のセットを保持したい場合は事前にコピーしておきましょう。
  • SortedSetは内部で常にソート済みの状態を維持するため、積集合の結果も昇順に並びます。
  • 引数には任意のIEnumerable<T>コレクションを渡せるため、Listや配列との積集合計算も可能です。
  1. 【C#】HashSetが指定されたコレクションの真部分集合かどうかを判定する方法

    C#の HashSet<T> クラスには、あるコレクションが別のコレクションに対して「真部分集合(proper subset)」であるかどうかを判定するためのメソッド IsProperSubsetOf() が用意されています。真部分集合とは、対象となるコレクションのすべての要素を含み、かつ相手側が自分には含まれない要素を少なくとも1つ持っている状態を指します。つまり、2つの集合が完全に一致する場合は「真部分集合」とは見なされず、False が返されます。この記事では、実際のコード例を使って IsProperSubsetOf() メソッドの使い方と動作を詳しく解説します。サンプルコー

  2. C#でListコレクションから要素を取得する方法

    C#では、List<T>コレクションに格納した要素へ、インデックスを指定するだけで簡単にアクセスできます。本記事では、Listから要素を取得する基本的な方法を、具体的なコード例とともに解説します。 Listへの要素の追加 まず、List<int>型のコレクションを作成し、Addメソッドを使って整数の要素を追加します。 List<int> list = new List<int>(); list.Add(20); list.Add(40); list.Add(60); list.Add(80); インデックスによる要素の取得 リストから特定の