简体   繁体   中英

C# - Comparing two lists of objects for changes with foreach

For my class assignment I need to compare an old list of students to a new list and add the new students, removed students, and changed students to separate lists.The instructor specified using nested foreach loops and not LINQ but my issue is breaking out of the loops once the old student list matches an entry in the new students and moving to the next student in the old list.

My code right now runs through the nested foreach, compares the entries to the first entry in the old list and as a result comes up without ID matches so it puts them in the removed list and ends the loops without moving on to the next student in the old list.

public static void CompareStudents(List<Student> oldList, List<Student> newList)
    {
        foreach (Student o in oldList)
        {
            foreach (Student n in newList)
            {
                if (FindStudent(o.ID, n.ID))
                {
                    if (CheckChanges(o, n))
                    {
                        changed.Add(n);
                        break;
                    }
                }
                else
                {
                    removed.Add(o);
                    break;
                }
            }
        }
    }

    private static bool FindStudent(string oldID, string newID)
    {
        if (newID.Equals(oldID))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public static bool CheckChanges(Student oldStu, Student newStu)
    {
        if (oldStu.FirstName.Equals(newStu.FirstName) && 
            oldStu.LastName.Equals(newStu.LastName) &&
            oldStu.StudentYear.Equals(newStu.StudentYear) &&
            oldStu.StudentRank.Equals(newStu.StudentRank))
        {
            return false;
        }
        else
        {
            return true;
        }
    }

How about using an Flag?

        foreach (Student o in oldList)
        {
            bool flag = false;
            foreach (Student n in newList)
            {
                if (FindStudent(o.ID, n.ID))
                {
                    if (CheckChanges(o, n))
                    {
                        changed.Add(n);
                        flag = true;
                        break;
                    }
                }
                else
                {
                    removed.Add(o);
                    flag = true;
                    break;
                }
            }
            if(flag) continue;
        }

If your Student class overrides the Equals method, then you can do the following :

public static void CompareStudents(List<Student> oldList, List<Student> newList)
{
    List<Student> added = new List<Student>();
    List<Student> removed = new List<Student>();
    List<Student> changed = new List<Student>();

    foreach(Student n in newList){
        // the added list is a subset of the newList so we begin by cloning the newList
        added.Add(n);
    }

    foreach (Student o in oldList)
    {
        bool existsInNewList = false;
        // we remove every o from the added list
        added.Remove(o);

        foreach (Student n in newList)
        {
            if (o.ID.Equals(n.ID))
            {
                // o and n have the same Id
                existsInNewList = true;
                if (!o.Equals(n))
                {
                    // o and n have the same Id but are different
                    changed.Add(n);
                    added.Remove(n);
                }
                // eventually add a break; here so you don't loop after you've found a n that matches o
            }
        }
        if(!existsInNewList){
            // none of the newStudents have the same Id as o
            removed.Add(o);
        }
    }
}

At the end you should have all three lists added , removed and changed filled with correct Students .

I think you should be using the code as under:

List<Student> OldStudents = new List<Student>();
List<Student> NewStudents = new List<Student>();
List<Student> StudentsEdit = new List<Student>();

 foreach (var oStud in OldStudents)
     {
        foreach (var nStud in NewStudents)
        {
          if (oStud != nStud)
            StudentsEdit.Add(oStud);
        }
     }

I Interpreted LINQ was suggested by Instructor, my bad, Hope this helps.

Regards,

N Baua

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM