私が考えることができる最も簡単な方法は、小さなLinqです。まず、表示されているものと同様に、すべての学生のペアを文字列のペアのリストとして取得します。動作するList<Tuple<string, string>>
はずです。注意が必要な点は、長方形の配列を使用していることです。これを IEnumerable として扱うと、奇妙なアクセス動作が発生します。
次に、2 つのペアが等しいかどうかを比較する方法が必要です。比較に使用するラムダ ステートメントを指定できるジェネリック クラスがあるので、カスタム比較ごとに単一目的の IEqualityComparer を実装する必要はありません。
public class GenericEqualityComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> equalityComparer;
private readonly Func<T, int> hashFunc;
public GenericEqualityComparer(Func<T, T, bool> compareFunc, Func<T,int> hashFunc)
:this(compareFunc)
{
this.equalityComparer = compareFunc;
this.hashFunc = hashFunc;
}
public GenericEqualityComparer(Func<T, T, bool> compareFunc)
{
this.equalityComparer = compareFunc;
this.hashFunc = o => o.GetHashCode();
}
public bool Equals(T x, T y)
{
return equalityComparer(x, y);
}
public int GetHashCode(T obj)
{
return hashFunc(obj);
}
}
次に、Linq の GroupBy() メソッドを介して値のリストを実行し、GenericEqualityComparer を指定して、カスタムの順序に依存しない方法で値を比較します。
var pairCounts = pairList
.GroupBy(p=>p, //key selector; we want the Tuple itself
new GenericEqualityComparer<Tuple<string,string>>(
(a,b)=>(a.Item1 == b.Item1 && a.Item2 == b.Item2)
|| (a.Item1 == b.Item2 && a.Item2 == b.Item1))
.Select(g=>new Tuple<string, int>(g.Key.Item1 + " - " + g.Key.Item2,
g.Count());
最終結果は、List<Tuple<string,int>>
見つかった名前の各ペアの最初の順列と、そのペアのいずれかの順列がリスト内でいくつ見つかったかを含む になります。