C# 比较列表<;字符串>;和列表<;T>;

C# 比较列表<;字符串>;和列表<;T>;,c#,list,compare,C#,List,Compare,我正在使用C#和框架4.0 我有一个字符串类型列表和另一个T类类型列表 如何将列表与列表进行比较并保存差异 private void simpleButton_Compare_Click(object sender, EventArgs e) { try { bool Is_Egal = true; int i = 0; foreach (string Od_Scan in Ordre_Scan)

我正在使用C#和框架4.0

我有一个字符串类型列表和另一个T类类型列表

如何将列表与列表进行比较并保存差异

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);
在我看来,给出的答案似乎是解决您的问题的一个很好的解决方案,它们解决了与列表比较有关的多个问题

编辑:但是,您应该更具体地说明您的需求,即“差异”到底是什么,例如{1,1,2}和{1,2}是否相同

以下是投票最多的答案。。。(包括在这里,只是因为某些原因(根据Bob的建议)将其移除)

" 说明: 我需要检查它们是否都有相同的元素,而不管它们在列表中的位置如何。每个MyType对象可能会在列表中出现多次。是否有一个内置函数来检查这一点?如果我保证每个元素在列表中只出现一次会怎么样

编辑:伙计们,谢谢你们的回答,但我忘了添加一些东西,每个元素在两个列表中出现的次数应该是相同的

回答: 如果您希望它们真正相等(即相同的项目和每个项目的相同数量),我认为最简单的解决方案是在比较之前进行排序:

Enumerable.SequenceEqual(list1.OrderBy(t => t), list2.OrderBy(t => t))
编辑: 这是一个性能更好(大约快十倍)的解决方案,只需要
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);
}
publicstaticboolscrambledequals(IEnumerablest1,IEnumerablest2){
var cnt=新字典();
foreach(列表1中的ts){
如果(cnt.ContainsKey){
cnt[s]++;
}否则{
cnt.添加(s,1);
}
}
foreach(列表2中的ts){
如果(cnt.ContainsKey){
cnt[s]-;
}否则{
返回false;
}
}
返回cnt.Values.All(c=>c==0);
}
编辑2: 要将任何数据类型作为键处理(例如Frank Tzanabetis指出的可为null的类型),您可以为字典创建一个采用a的版本:

public static bool ScrambledEquals<T>(IEnumerable<T> list1, IEnumerable<T> list2, IEqualityComparer<T> comparer) {
  var cnt = new Dictionary<T, int>(comparer);
  ...
publicstaticboolscrambledequals(IEnumerable列表1、IEnumerable列表2、IEqualityComparer比较器){
var cnt=新字典(比较器);
...

您可以在
Pers\u Compare
类上实现IComparable,该类类似于:

    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;

在你的
Pers\u Compare
类型上实现
IComparable
?你是不是刚刚完成了一些lisp编程?只是一个建议,移动到camelCasing.用英文名称命名类/变量也是一个很好的做法-顺便说一句,你是德国人吗?:)我不认为他是德国人,根据MessageBoxtext我更建议他是德国人french@WiiMaxx还包括元语法“azer”、“qsdf”和“wxcv”,它们是AZERTY键盘(法语或比利时)上每行的前四个键。如果问题被删除,您可能应该添加说明/示例/代码,而不仅仅是一个链接。
    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;