2つのリストを比較する 順序を無視して、等価性を求めるオブジェクト [重複] 質問する

2つのリストを比較する 順序を無視して、等価性を求めるオブジェクト [重複] 質問する

また別のリスト比較の質問です。

List<MyType> list1;
List<MyType> list2;

リスト内の位置に関係なく、両方に同じ要素があることを確認する必要があります。各MyTypeオブジェクトはリストに複数回出現する場合があります。これをチェックする組み込み関数はありますか? 各要素がリストに 1 回だけ出現することを保証したらどうなりますか?

編集:皆さん、回答ありがとうございます。ただし、追加するのを忘れていました。各要素の出現回数は、両方のリストで同じである必要があります。

ベストアンサー1

本当に同じにしたい場合(つまり、同じアイテムで、各アイテムの数も同じ)、最も簡単な解決策は比較する前に並べ替えることだと思います。

Enumerable.SequenceEqual(list1.OrderBy(t => t), list2.OrderBy(t => t))

編集:

以下に、パフォーマンスが少し向上し (約 10 倍高速)、 ではなく のみを必要とするソリューションを示しIEquatableますIComparable

public static bool ScrambledEquals<T>(IEnumerable<T> list1, IEnumerable<T> list2) {
  var cnt = new Dictionary<T, int>();
  foreach (T s in list1) {
    if (cnt.ContainsKey(s)) {
      cnt[s]++;
    } else {
      cnt.Add(s, 1);
    }
  }
  foreach (T s in list2) {
    if (cnt.ContainsKey(s)) {
      cnt[s]--;
    } else {
      return false;
    }
  }
  return cnt.Values.All(c => c == 0);
}

編集2:

任意のデータ型をキーとして扱うには(例えばFrank Tzanabetisが指摘したようにnull許容型など)、比較子辞書の場合:

public static bool ScrambledEquals<T>(IEnumerable<T> list1, IEnumerable<T> list2, IEqualityComparer<T> comparer) {
  var cnt = new Dictionary<T, int>(comparer);
  ...

おすすめ記事