0

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;
        }
    }
  • Ahhh so what's your question? Do you just want us to finish your homework for you? – rory.ap May 15 '17 at 11:24
  • http://stackoverflow.com/questions/5636438/difference-between-two-lists – Fredrik May 15 '17 at 11:30
  • Where is the removed list declared? Your requirements are not clear. – CRice May 15 '17 at 11:37
  • `FindStudents()` method is useless (can be replaced with simple comparison `o.ID == n.ID`). But algorithm is also not the best. Imagine you have coins in left and in right hand. Instead of keeping them all the time and comparing each with each you would rather try to **find** same coins and **remove** them from future search. What is left - is what doesn't match. – Sinatr May 15 '17 at 11:39
  • I'm voting to close this question as off-topic because this question is asking for a _specific_ homework solution that foregoes any other equally valid solution (e.g. LINQ). – Flater May 15 '17 at 11:47
  • The problem in your code regarding `break;` statements is that you will leave the inner `foreach` almost every time you enter it, because the first element of the newList is more likely to be different from the current element of the oldList so you'll end up in the `else` and `break;`. So you don't move on to the next student in the **new list**, but instead break out of this loop and move on to the next student in the **old list**, and so on until the very end. – Rafalon May 15 '17 at 12:51

3 Answers3

1

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.

Rafalon
  • 4,450
  • 2
  • 16
  • 30
  • Thanks, this works. I just had to implement the CheckChanges method. My instructor provided us with the nested foreach as a suggestion to start with so I was stuck in that line of thinking. –  May 15 '17 at 23:46
0

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;
        }
LWS
  • 329
  • 3
  • 15
-1

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

NBaua
  • 583
  • 4
  • 16
  • 33
  • *...The instructor specified using nested foreach loops and not LINQ...* – Sinatr May 15 '17 at 11:36
  • also this makes no difference between added, removed and changed items, and you even **miss** added students as you take result values from the old student list (so does the OP) – Rafalon May 15 '17 at 11:39
  • Woah ! Your edit is even worse as your StudentsEdit list is going to contain way too many students (think about for each student in the old list, almost every student of the new list is different from it so you will add it to your edit list) – Rafalon May 15 '17 at 11:50
  • Your example will be adding **every** `oStud` object to the resulting list **several** times. Several = for every `nStud` that exists and is different (most often `NewStudents.Length - 1`) . Wrong output, no differentiation between edited, added and deleted, plus a faulty equality comparison. This code is not an answer to the question that is asked. – Flater May 15 '17 at 11:50