0

C# とフレームワーク 4.0 を使用しています。

文字列型のリストとクラス T 型の別のリストがあります。

List と List を比較して、違いを保存するにはどうすればよいですか?

private void simpleButton_Compare_Click(object sender, EventArgs e)
{
    try
    {
        bool Is_Egal = true;                 

        int i = 0;
        foreach (string Od_Scan in Ordre_Scan)
        {
            if (!Outils.Get_Ordre_Donne()[i].NoOrdre.Contains(Od_Scan) && !String.IsNullOrWhiteSpace(Od_Scan))
            {
                Is_Egal = false;
                Temp_Od_Scan.Add(Od_Scan);
            }                    
            i++;
        }

        foreach (Pers_Compare Od_Done in Outils.Get_Ordre_Donne())
        {
            if (!Ordre_Scan.Contains(Od_Done.NoOrdre) && !String.IsNullOrWhiteSpace(Od_Done.NoOrdre))
            {
                Is_Egal = false;
                Temp_Od_Donne.Add(Od_Done);
            }
            else
            {
                Temp_Od_Donne_Egal.Add(Od_Done);
            }
        }

        if (Is_Egal)
        { 
            MessageBox.Show("égalité");
        }
        else
        { 
            MessageBox.Show("PAS égalité"); 
        }

     }
     catch (Exception excThrown)
     {
         MessageBox.Show(excThrown.Message);
     }
 }

とデータ:

List<string> Ordre_Scan= new List<string> { "azer","qsdf"};

Pers_Compare obj = new Pers_Compare();
obj.Nolv = 1;
obj.Noordre = "qsdf"

Pers_Compare obj2 = new Pers_Compare();
obj2.Nolv = 1;
obj2.Noordre = "wxcv"

List<Pers_Compare> Ordre_Donne = new List<Pers_Compare>();
Ordre_Donne.add(obj);
Ordre_Donne.add(obj2);

また、データを Ordre_Donne に保存したいのですが、Od_Scan には保存したくありません。

foreach (string Od_Scan in Temp_Od_Scan)
{
    all item that not found in List A
    -->  wxcv
}

foreach (var Od_Done in Temp_Od_Donne)
{
    all item that not found in List B
    -->   azer
}
4

3 に答える 3

1

少し異なる質問(リストを別のリストと比較する)に対する答えは、あなたの問題の良い解決策のように思えます。リストの比較に関する複数の問題に対処しています。

編集:ただし、要件をより具体的にする必要があります。つまり、「違い」とは正確には何ですか?たとえば、{1,1,2} と {1,2} は同じですか?

これが最も多くの票を集めた答えです...(ここに含まれているのは、何らかの理由で削除された場合だけです(ボブの提案による))

" 説明: リスト内の位置に関係なく、両方が同じ要素を持っていることを確認する必要があります。各 MyType オブジェクトは、リストに複数回表示される場合があります。これを確認する組み込み関数はありますか?各要素はリストに一度だけ表示されますか?

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

ANSWER : それらを本当に等しくしたい場合 (つまり、同じ項目と各項目の同じ数)、最も簡単な解決策は、比較する前に並べ替えることだと思います。

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);
  ...

"

于 2013-06-14T13:06:22.660 に答える
0
  var list1 = Ordre_Donne.Where(o => !Ordre_Scan.Any(s => s == o.Noordre));
  var list2 = Ordre_Scan.Where(s => !Ordre_Donne.Any(o => o.Noordre == s));
于 2013-06-14T13:15:27.027 に答える
0

クラスにIComparable を実装することもできますPers_Compare。これは次のようになります。

    public int CompareTo(string other)
    {
        return this.Noordre.CompareTo(other);
    }

または、データ構造を制御できない場合は、次のようなことができます

var Temp_Od_Donne = from od in Ordre_Donne
                    where !Ordre_Scan.Contains(od.Noordre)
                    select od;

var Temp_Od_Scan = from os in Ordre_Scan
                   where !Ordre_Donne.Select(od => od.Noordre).Contains(os)
                   select os;
于 2013-06-14T13:20:19.070 に答える