比较List <string>和List <t> </t> </string>

时间:2013-06-14 12:52:58

标签: c# list compare

我正在使用C#和framework 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
}

3 个答案:

答案 0 :(得分:1)

我认为for a slightly different question (comparing a List with another List)的答案对您的问题来说是一个很好的解决方案,它们解决了与列表比较有关的多个问题。

编辑:但是你应该更具体地了解你的要求,即究竟什么是'差异',例如是{1,1,2}和{1,2}是一样的吗?

这是给出最多选票的答案......(此处包含的内容因为某些原因而被删除(根据Bob的建议))

” 的说明: 我需要检查它们是否具有相同的元素,无论它们在列表中的位置如何。每个MyType对象可能在列表中出现多次。是否有内置函数可以检查这个?如果我保证每个元素只在列表中出现一次怎么办?

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

<强> ANSWER : 如果你希望它们真的相同(即每个项目的相同项目和相同数量),我认为最简单的解决方案是在比较前进行排序:

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

编辑2:

要将任何数据类型作为键处理(例如Frank Tzanabetis所指出的可空类型),您可以为字典创建一个comparer的版本:

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

答案 1 :(得分: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));

答案 2 :(得分:0)

您可以在Pers_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;