如何在两个列表中找出差异?

时间:2022-09-10 21:32:26

As you can see below I need to have an output for showing additions, changes, and removed students. Thought I have researched how to exactly do this and kept finding what I have setup currently in RemovedStudents(). Does anyone have any examples that could help me finish this up for the additions, changes and removed students methods? I would appreciate any help on this!

正如您在下面所见,我需要有一个输出来显示添加,更改和删除的学生。我以为我已经研究过如何准确地做到这一点并继续在RemovedStudents()中找到我目前设置的内容。有没有人有任何可以帮助我完成添加,更改和删除学生方法的示例?我将不胜感激任何帮助!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace OldandNewStudents
{
    class Program
    {
        static void Main(string[] args)
        {
            //Display lists of students
            Console.WriteLine("Here is the list of old students: ");
            ShowStudents(GetStudentsOld());
            Console.WriteLine("Here is the list of new students: ");
            ShowStudents(GetStudentsNew());

            //Show the additions
            Console.WriteLine("Here is the list Additions: ");

            //Show the changes
            Console.WriteLine("Here is the list of Changes: ");

            //Show the removed students
            Console.WriteLine("Here is the list of removed students: ");
            RemovedStudents(GetStudentsNew(), GetStudentsOld());
            Console.ReadLine();
        }

        public static List<Student> GetStudentsOld()
        {
            List<Student> students = new List<Student>();

            students.Add(new Student("111", "Michael", "Tucker", "Junior", 10));
            students.Add(new Student("222", "Svetlana", "Omelchenko", "Senior", 2));
            students.Add(new Student("333", "Michiko", "Osada", "Senior", 7));
            students.Add(new Student("444", "Hugo", "Garcia", "Junior", 16));
            students.Add(new Student("555", "Cesar", "Garcia", "Freshman", 4));
            students.Add(new Student("666", "Fadi", "Fakhouri", "Senior", 72));
            students.Add(new Student("777", "Hanying", "Feng", "Senior", 11));
            students.Add(new Student("888", "Debra", "Garcia", "Junior", 41));
            students.Add(new Student("999", "Terry", "Adams", "Senior", 6));
            students.Add(new Student("211", "Bob", "Stephenson", "Junior", 150));
            return students;
        }

        public static List<Student> GetStudentsNew()
        {
           List<Student> students = new List<Student>();

            students.Add(new Student("111", "Michael", "Tucker", "Junior", 10));
            students.Add(new Student("222", "Svetlana", "Omelchenko", "Senior", 2));
            students.Add(new Student("333", "Michiko", "Osada", "Senior", 7));
            students.Add(new Student("311", "Sven", "Mortensen", "Freshman", 53));
            students.Add(new Student("444", "Hugo", "Garcia", "Freshman", 16));
            students.Add(new Student("555", "Cesar", "Garcia", "Freshman", 4));
            students.Add(new Student("666", "Fadi", "Fakhouri", "Senior", 72));
            students.Add(new Student("777", "Hanying", "Feng", "Senior", 11));
            students.Add(new Student("888", "Debra", "Garcia", "Junior", 41));
            students.Add(new Student("411", "Lance", "Tucker", "Junior", 60));
            students.Add(new Student("999", "Terry", "Adams", "Senior", 6));
            return students;
        }

        public static void ShowStudents(List<Student> stuList)
        {
            Console.WriteLine();

            foreach (Student s in stuList)
            {
                Console.WriteLine(s);
            }
            Console.WriteLine();
        }

        public static void RemovedStudents(List<Student> stuNewList, List<Student> stuOldList)
        {
            List<Student> removedStudents = stuNewList.Except(stuOldList).ToList();
            IEnumerable<Student> differenceQuery = stuNewList.Except(stuOldList);
            foreach (Student s in differenceQuery)
                Console.WriteLine(s);
        }
    }
}

Here is my new updated RemovedStudents Method:

这是我新更新的RemovedStudents方法:

public static void RemovedStudents(List<Student> stuNewList, List<Student> stuOldList)
    {
        GetStudentsOld().Except(GetStudentsNew());
        foreach (Student s in stuNewList)
            Console.WriteLine("student: {0} {1}", s.FirstName, s.LastName);
    }

Here is the Student Class, though I am not allowed to edit it:

这是学生班,但我不允许编辑它:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OldandNewStudents
{
public class Student
{
    // Sample Student class
    // Each student has a first name, a last name, a class year, and a rank 
    // that indicates academic ranking in the student body.

    public string ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string StudentYear { get; set; }
    public int StudentRank { get; set; }

    public Student(string idNumber, string firstName, string lastName, string studentYear, int studentRank)
    {
        ID = idNumber;
        FirstName = firstName;
        LastName = lastName;
        StudentYear = studentYear;
        StudentRank = studentRank;
    }


    public override string ToString()
    {
        return ID + " " + FirstName + " " + LastName + " " + StudentYear + " " + StudentRank;
    }
}
}

Here is my NEW addition method, but I'm not sure why I am getting an overload error:

这是我的新增加方法,但我不确定为什么我收到过载错误:

public static List<Student> GetActualNewStudents(List<Student> oldStudents, List<Student> newStudents)
    {
        List<Student> actualNewStudents = new List<Student>();

        foreach (var student in oldStudents) {
            if (oldStudents[student].ID != newStudents[student].ID)
            {
                actualNewStudents.Add(newStudents[student]);
            }
        }

        return actualNewStudents;
    }

3 个解决方案

#1


0  

The problem with using the two lists you have are the comparisons, such as the Except extension method will be using the default implementation for the IEquatable. You have an a constructor, but the class definition is not included. If the fields and properties only contain value types, then a byte by byte comparison is applied. If you have any reference types then you will need to override the default Equals method. If you only have value type fields, then the following code should work.

使用这两个列表的问题是比较,例如Except扩展方法将使用IEquatable的默认实现。您有一个构造函数,但不包括类定义。如果字段和属性仅包含值类型,则应用逐字节比较。如果您有任何引用类型,则需要覆盖默认的Equals方法。如果您只有值类型字段,则以下代码应该有效。

addition:

GetStudentsNew().Except(GetStudentsOld());

removed:

GetStudentsOld.Except(GetStudentsNew());

difference:

public diff(IEnumerable<Student> new, IEnumberable<Student> old)
{
    var both = new.AddRange(old); 
    var add = both.Except(new);
    return add.Except(old);
}

I should note that Console.WriteLine will not work as you expect, as you are passing in a reference type, and not a type that will be converted to the string you expect.

我应该注意,Console.WriteLine将无法正常工作,因为您传入的是引用类型,而不是将转换为您期望的字符串的类型。

#2


0  

What you could do is create a third array with the common students, then for all the students that aren't there, consider a new student in the new students array, of course:

你可以做的是与普通学生一起创建第三个数组,然后对于那些不在那里的学生,考虑新学生数组中的新学生,当然:

EDIT:

public static List<Student> GetActualNewStudents(List<Student> oldStudents, List<Stident> newStudents)
    {
        var actualNewStudents = new List<Student>();
        foreach (var item in newStudents)
        {
            if (!oldStudents.Contains(item))
                actualNewStudents.Add(item);

        }
        return actualNewStudents;
    }

#3


0  

This worked and got me the results I needed:

这工作,并得到了我需要的结果:

Code for additions:

增补代码:

public static List<Student> GetActualNewStudents(List<Student> oldStudents, List<Student> newStudents)
    {
        //Show the new students
        List<Student> actualNewStudents = newStudents.Where(y => !oldStudents.Any(z => z.ID == y.ID)).ToList();

        return actualNewStudents;
    }

Code for Removed Students:

被移除学生代码:

public static List<Student> GetActualRemovedStudents(List<Student> oldStudents, List<Student> newStudents)
    {
        //Show the removed students
        List<Student> actualRemovedStudents = oldStudents.Where(y => !newStudents.Any(z => z.ID == y.ID)).ToList();

        return actualRemovedStudents;
    }

Code for Changes:

变更代码:

public static List<Student> GetActualChangedStudents(List<Student> oldStudents, List<Student> newStudents)
    {
        //Show the changes
        List<Student> actualChangedStudents = newStudents.Where(y => !oldStudents.Any(z => z.FirstName == y.FirstName && z.LastName == y.LastName && z.StudentRank == y.StudentRank && z.StudentYear == y.StudentYear)).ToList();

        return actualChangedStudents;
    }

#1


0  

The problem with using the two lists you have are the comparisons, such as the Except extension method will be using the default implementation for the IEquatable. You have an a constructor, but the class definition is not included. If the fields and properties only contain value types, then a byte by byte comparison is applied. If you have any reference types then you will need to override the default Equals method. If you only have value type fields, then the following code should work.

使用这两个列表的问题是比较,例如Except扩展方法将使用IEquatable的默认实现。您有一个构造函数,但不包括类定义。如果字段和属性仅包含值类型,则应用逐字节比较。如果您有任何引用类型,则需要覆盖默认的Equals方法。如果您只有值类型字段,则以下代码应该有效。

addition:

GetStudentsNew().Except(GetStudentsOld());

removed:

GetStudentsOld.Except(GetStudentsNew());

difference:

public diff(IEnumerable<Student> new, IEnumberable<Student> old)
{
    var both = new.AddRange(old); 
    var add = both.Except(new);
    return add.Except(old);
}

I should note that Console.WriteLine will not work as you expect, as you are passing in a reference type, and not a type that will be converted to the string you expect.

我应该注意,Console.WriteLine将无法正常工作,因为您传入的是引用类型,而不是将转换为您期望的字符串的类型。

#2


0  

What you could do is create a third array with the common students, then for all the students that aren't there, consider a new student in the new students array, of course:

你可以做的是与普通学生一起创建第三个数组,然后对于那些不在那里的学生,考虑新学生数组中的新学生,当然:

EDIT:

public static List<Student> GetActualNewStudents(List<Student> oldStudents, List<Stident> newStudents)
    {
        var actualNewStudents = new List<Student>();
        foreach (var item in newStudents)
        {
            if (!oldStudents.Contains(item))
                actualNewStudents.Add(item);

        }
        return actualNewStudents;
    }

#3


0  

This worked and got me the results I needed:

这工作,并得到了我需要的结果:

Code for additions:

增补代码:

public static List<Student> GetActualNewStudents(List<Student> oldStudents, List<Student> newStudents)
    {
        //Show the new students
        List<Student> actualNewStudents = newStudents.Where(y => !oldStudents.Any(z => z.ID == y.ID)).ToList();

        return actualNewStudents;
    }

Code for Removed Students:

被移除学生代码:

public static List<Student> GetActualRemovedStudents(List<Student> oldStudents, List<Student> newStudents)
    {
        //Show the removed students
        List<Student> actualRemovedStudents = oldStudents.Where(y => !newStudents.Any(z => z.ID == y.ID)).ToList();

        return actualRemovedStudents;
    }

Code for Changes:

变更代码:

public static List<Student> GetActualChangedStudents(List<Student> oldStudents, List<Student> newStudents)
    {
        //Show the changes
        List<Student> actualChangedStudents = newStudents.Where(y => !oldStudents.Any(z => z.FirstName == y.FirstName && z.LastName == y.LastName && z.StudentRank == y.StudentRank && z.StudentYear == y.StudentYear)).ToList();

        return actualChangedStudents;
    }