There is a structure and you need to sort it by different fields. Through CompareTo, sorting by only one field is obtained

struct Student : IComparable<Student> { public string fio; public string group; public int[] performance; public int CompareTo(Student student) { return this.fio.CompareTo(student.fio); } } 
  • Look here and here - AK
  • need to sort it by different fields - for what? Through CompareTo, sorting out by only one field is obtained - nothing prevents to check several fields - Grundy
  • one
    So add sorting by other fields in CompareTo - tym32167

1 answer 1

Suppose there is a class Person

 class Person { public string Name{get;} public string LastName{get;} public Person(string name, string lastName) { Name = name; LastName = lastName; } } 

We will sort the collection of such classes by name and surname. Let's write a comparator

 class PersonComparer : IComparer<Person> { public int Compare(Person x, Person y) { var ret =string.CompareOrdinal(x.LastName, y.LastName); if(ret != 0) return ret; return string.CompareOrdinal(x.Name, y.Name); } } 

Apparently, at first there is a sorting by a surname. But if the surname matches, then we sort by name.

How to use:

 var data = new[] { new Person("Vasya", "Pupkin"), new Person("Petya", "Pupkin"), new Person("Alesha", "Pupkin"), new Person("Vasya", "Borisov"), }; Array.Sort(data, new PersonComparer()); foreach (var p in data) Console.WriteLine($"{p.LastName} {p.Name}"); 

Conclusion

 Borisov Vasya Pupkin Alesha Pupkin Petya Pupkin Vasya 

If you need a comparators factory, here's an example.

 static class PersonComparer { public static IComparer<Person> Create<T>(Func<Person, T> accessor)where T : IComparable { return new PersonComparerImpl<T>(accessor); } class PersonComparerImpl<T> : IComparer<Person> where T : IComparable { Func<Person, T> _accessor; public PersonComparerImpl(Func<Person, T> accessor) { _accessor = accessor; } public int Compare(Person x, Person y) { return Comparer.Default.Compare(_accessor(x),_accessor(y)); } } } 

How to use

 var data = new[] { new Person("Vasya", "Pupkin"), new Person("Petya", "Pupkin"), new Person("Alesha", "Pupkin"), new Person("Vasya", "Borisov"), }; Array.Sort(data, PersonComparer.Create(p => p.LastName)); foreach (var p in data) Console.WriteLine($"{p.LastName} {p.Name}"); Console.WriteLine("--------------------------"); Array.Sort(data, PersonComparer.Create(p => p.Name)); foreach (var p in data) Console.WriteLine($"{p.LastName} {p.Name}"); 

Conclusion

 Borisov Vasya Pupkin Vasya Pupkin Petya Pupkin Alesha -------------------------- Pupkin Alesha Pupkin Petya Borisov Vasya Pupkin Vasya 

Developing the theme, you can roll the factory to sort by several fields. Example

 static class PersonComparer { public static IComparer<Person> Create(params Func<Person, IComparable>[] accessors) { return new PersonComparerImpl(accessors); } class PersonComparerImpl : IComparer<Person> { Func<Person, IComparable>[] _accessors; public PersonComparerImpl(Func<Person, IComparable>[] accessors) { _accessors = accessors; } public int Compare(Person x, Person y) { foreach (var accessor in _accessors) { var ret = Comparer.Default.Compare(accessor(x), accessor(y)); if (ret != 0) return ret; } return 0; } } } 

How to use

 var data = new[] { new Person("Vasya", "Pupkin"), new Person("Petya", "Pupkin"), new Person("Alesha", "Pupkin"), new Person("Vasya", "Borisov"), }; Array.Sort(data, PersonComparer.Create(p => p.LastName)); foreach (var p in data) Console.WriteLine($"{p.LastName} {p.Name}"); Console.WriteLine("--------------------------"); Array.Sort(data, PersonComparer.Create(p => p.Name)); foreach (var p in data) Console.WriteLine($"{p.LastName} {p.Name}"); Console.WriteLine("--------------------------"); Array.Sort(data, PersonComparer.Create(p => p.LastName, p=>p.Name)); foreach (var p in data) Console.WriteLine($"{p.LastName} {p.Name}"); 

Conclusion

 Borisov Vasya Pupkin Vasya Pupkin Petya Pupkin Alesha -------------------------- Pupkin Alesha Pupkin Petya Borisov Vasya Pupkin Vasya -------------------------- Borisov Vasya Pupkin Alesha Pupkin Petya Pupkin Vasya 
  • Thank you, in general, you helped, I just asked a bit incorrectly. In my case, the solution would be to write 3 classes of comparator, for each field, or one and in the constructor to transfer to it by what field to sort - Sectarian
  • @Sectarian updated the answer - tym32167