compare List<string> and List<T>

别说谁变了你拦得住时间么 提交于 2020-01-24 00:45:11

问题


I'm using C# and framework 4.0.

I have a list of type string and another list of type class T;

How can I compare List with a List and save the difference?

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

and the data :

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

And I want to save the data in Ordre_Donne but not in Od_Scan and vice versa.

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
}

回答1:


The answer given for a slightly different question (comparing a List with another List) seems to me to be a good solution for your issue, they address multiple issues to do with comparisons of lists.

EDIT: However you should be more specific with your requirements i.e. what exactly is a 'difference', e.g. is {1,1,2} and {1,2} the same?

Here is the answer given the most votes... (included here just encase it gets removed for some reason (as per Bob' suggestion))

" DESCRIPTION: I need to check that they both have the same elements, regardless of their position within the list. Each MyType object may appear multiple times on a list. Is there a built-in function that checks this? What if I guarantee that each element appears only once in a list?

EDIT: Guys thanks for the answers but I forgot to add something, the number of occurrences of each element should be the same on both lists.

ANSWER: If you want them to be really equal (i.e. the same items and the same number of each item), I think that the simplest solution is to sort before comparing:

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

Edit:

Here is a solution that performs a bit better (about ten times faster), and only requires IEquatable, not 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);
}

Edit 2:

To handle any data type as key (for example nullable types as Frank Tzanabetis pointed out), you can make a version that takes a comparer for the dictionary:

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

"




回答2:


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



回答3:


You can either implement IComparable on your Pers_Compare class, which will look something like:

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

Or, if you don't have control of the data structure, you could do something like

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;


来源:https://stackoverflow.com/questions/17108906/compare-liststring-and-listt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!