2016-08-30 2 views
-1

Хорошо, поэтому я пытаюсь сравнить два списка с методом для отображения новых элементов во втором списке. Списки печатаются жестко и в отдельных методах распечатываются на консоли. Единственный способ, которым я смог вытащить каждую запись из обоих списков, - это использовать цикл foreach, но он всегда относится к утверждению о том, что каждая запись не равна, даже если записи являются одинаковыми. Я не знаю, почему это происходит.Сравнение двух списков C#

Вот два закодированных списки

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

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

    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 StudentIDMatch(List<Student> students, List<Student> student) 
    { 


     foreach (var ID in students) 
     { 
      bool isMatch = false; 
      do 

       foreach (var ID2 in student) 
       { 
        if (ID2 != ID) 
        { 

         isMatch = false; 
        } 
        else if (ID.Equals(ID2)) 
        { 
         isMatch = false; 
        } 
       } 
      while (!isMatch); 

     } 
    } 

в конечном счете, я пытаюсь найти различия и печатать их вне. Я знаю, что это не совсем, но мне нужно выяснить, как правильно их сравнить, прежде чем я начну заниматься тем, как их распечатать. Также я знаю, что цикл Do While не правильный, и мне нужно его повторить, после того как это исправлено.

Спасибо!

+1

http://stackoverflow.com/questions/5636438/difference-between-two-lists –

+1

вы пробовали простой поиск Google о том, как 'Сравните Список ' – MethodMan

+1

http://stackoverflow.com/questions/12795 882/quickest-to-compare-two-list – astidham2003

ответ

1

Во-первых, есть ошибка в

else if (ID.Equals(ID2)) 
        { 
         isMatch = false; 
        } 

вероятно Вы имели в виду isMatch = истина;

При этом .NET Framework предоставляет множество инструментов для сравнения двух списков.

Если то, что вы хотите, чтобы извлечь новые элементы во втором списке, вы могли бы использовать что-то вроде этого: students1.Where(student1 => !students2.Any(student2 => student2 != student1)).ToList();

Если ваша цель состоит в том, чтобы изолировать студентов из одного списка, которые не в другом перечислите оба способа, вы можете сделать это дважды и присоединиться к результатам. Это самое легкое и быстрое решение, с которым я мог бы прийти. Если вы не хотите потратить время на разработку своего собственного алгоритма. Вы можете использовать эту инфраструктуру.

+1

'.Except' - это еще один способ сформулировать то, что я написал –

0

Если вы делаете матч на одной только ID, то вы можете сделать что-то вроде этого:

List<int> newStudentsList = newStudents.Select(n => n.Id).ToList(); 
List<int> oldStudentsList = oldStudents.Select(o => o.Id).ToList(); 

var missingStudents = oldStudentsList.Except(newStudentsList).ToList(); 

Это строит список из Ид от каждого исходного списка, а затем создать новый список все ИД, которые существуют в одном, но не в другом.

+0

Это расскажет вам о старых учениках, которые не вернулись, но не будут дайте вам любого нового ученика. – EJoshuaS

+0

@EJoshuaS: обратный сбор заказ ... смотри мой ответ. – IAbstract

+0

Нет причин создавать эти промежуточные списки, если они не сортируются до сопоставления. – IAbstract

0

Если каждый студент имеет уникальный идентификатор, вы можете заменить следующие два метода в классе Student:

public override bool Equals(object obj) 
{ 
    return ID == (obj as Student).ID; 
} 

public override int GetHashCode() 
{ 
    return ID; 
} 

А затем найти различия, как это:

var diff = GetStudentsNew().Except(GetStudentsOld()).ToList(); 
+0

Или реализовать 'IEqualityComparer '. – IAbstract

0

я изложил вы можете найти несколько способов сравнения коллекций. Одно замечание: если коллекции отсортированы ранее, сравнение будет быстрее.

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     var oldStudents = GetStudentsOld(); 
     var newStudents = GetStudentsNew(); 

     Console.WriteLine("Using 'Except' with 'IEqualityComparer<Student>'"); 
     WriteDropOutsWithExcept(oldStudents, newStudents); 
     Console.WriteLine(); 
     WriteNewStudentsWithExcept(oldStudents, newStudents); 
     Console.WriteLine("********************************************************"); 
     Console.WriteLine(); 

     Console.WriteLine("Using 'Compare' linq with 'Key' selector"); 
     WriteDropOutsWithKey(oldStudents, newStudents); 
     Console.WriteLine(); 
     WriteNewStudentsWithKey(oldStudents, newStudents); 
     Console.WriteLine("********************************************************"); 
     Console.WriteLine(); 

     Console.WriteLine("Using 'Compare' linq with 'StrategyComparer<Student>'"); 
     WriteDropOutsWithStrategyComparer(oldStudents, newStudents); 
     Console.WriteLine(); 
     WriteNewStudentsWithStrategyComparer(oldStudents, newStudents); 

     Console.ReadKey(); 
    } 

    private static void WriteDropOutsWithExcept(List<Student> oldStudents, List<Student> newStudents) 
    { 
     Console.WriteLine("Dropped from enrollment:"); 
     foreach (var student in oldStudents.Compare(newStudents, new StudentComparer())) 
     { 
      Console.WriteLine(student); 
     } 
    } 

    private static void WriteNewStudentsWithExcept(List<Student> oldStudents, List<Student> newStudents) 
    { 
     Console.WriteLine("Added to enrollment:"); 
     foreach (var student in newStudents.Compare(oldStudents, new StudentComparer())) 
     { 
      Console.WriteLine(student); 
     } 
    } 

    private static void WriteDropOutsWithKey(List<Student> oldStudents, List<Student> newStudents) 
    { 
     Console.WriteLine("Dropped from enrollment:"); 
     foreach (var student in oldStudents.Compare(newStudents, s => s.Id)) 
     { 
      Console.WriteLine(student); 
     } 
    } 

    private static void WriteNewStudentsWithKey(List<Student> oldStudents, List<Student> newStudents) 
    { 
     Console.WriteLine("Added to enrollment:"); 
     foreach (var student in newStudents.Compare(oldStudents, s => s.Id)) 
     { 
      Console.WriteLine(student); 
     } 
    } 

    private static void WriteDropOutsWithStrategyComparer(List<Student> oldStudents, List<Student> newStudents) 
    { 
     Console.WriteLine("Dropped from enrollment:"); 
     foreach (var student in oldStudents.Compare(newStudents, new StrategyComparer<Student, int>(k => k.Id))) 
     { 
      Console.WriteLine(student); 
     } 
    } 

    private static void WriteNewStudentsWithStrategyComparer(List<Student> oldStudents, List<Student> newStudents) 
    { 
     Console.WriteLine("Added to enrollment:"); 
     foreach (var student in newStudents.Compare(oldStudents, new StrategyComparer<Student, int>(k => k.Id))) 
     { 
      Console.WriteLine(student); 
     } 
    } 

    private class StudentComparer : IEqualityComparer<Student> 
    { 
     public bool Equals(Student x, Student y) 
     { 
      return x.Id == y.Id; 
     } 

     public int GetHashCode(Student obj) 
     { 
      return obj.Id.GetHashCode(); 
     } 
    } 

    private class StrategyComparer<TModel, TKey> : IStrategyComparer<TModel> 
    { 
     private readonly Func<TModel, TKey> _keySelector; 

     public StrategyComparer(Func<TModel, TKey> keySelector) 
     { 
      _keySelector = keySelector; 
     } 

     public bool Equals(TModel x, TModel y) 
     { 
      return Equals(_keySelector(x), _keySelector(y)); 
     } 

     public int GetHashCode(TModel obj) 
     { 
      return _keySelector(obj).GetHashCode(); 
     } 
    } 
} 

internal interface IStrategyComparer<in TModel> : IEqualityComparer<TModel> 
{ 
} 

public static class CollectionUtils 
{ 
    // Compare using Linq 
    public static IEnumerable<TModel> Compare<TModel, TKey>(this IEnumerable<TModel> source1, 
     IEnumerable<TModel> source2, Func<TModel, TKey> key) 
    { 
     return source1.Where(model => !source2.Any(m => Equals(key(m), key(model)))); 
    } 

    // Compare using Except/Except with comparer 
    public static IEnumerable<TModel> Compare<TModel>(this IEnumerable<TModel> source1, IEnumerable<TModel> source2, 
     IEqualityComparer<TModel> comparer = null) 
    { 
     if (comparer == null) 
     { 
      return source1.Except(source2); 
     } 

     return source1.Except(source2, comparer); 
    } 

    // Compare using Linq with StrategyComparer 
    public static IEnumerable<TModel> Compare<TModel>(this IEnumerable<TModel> source1, 
     IEnumerable<TModel> source2, IStrategyComparer<TModel> comparer) { 
     return source1.Where(model => !source2.Any(m => comparer.Equals(model, m))); 
    } 
} 

Выход:

Использование 'За исключением' с 'IEqualityComparer'
Выпало из регистрации:
[150] Стефенсон, Боб :: Младший (211)

Добавлено в Зачисление:
[53] Mortensen, Sven :: Первокурсник (311)
[60] Tucker, Lance :: Junior (411)


Использование 'Сравнить' с селектором LINQ 'Key'
Выпало из регистрации:
[150] Stephenson, Боб :: Младший (211)

Добавлено в регистрации:
[53] Мортенсен, Свен :: Первокурсник (311)
[60] Такер, Lance :: Младший (411)


Использование 'Сравнить' LINQ с 'StrategyComparer'
Выпало из регистрации:
[150] Стефенсон, Боб :: Младший (211)

В дополнение к регистрации:
[53] Мортенсен, Свен :: Первокурсник (311)
[60] Tucker, Lance :: Младший (411)

Смежные вопросы