V
V
Vasily Vasilyev2017-09-29 17:54:29
C++ / C#
Vasily Vasilyev, 2017-09-29 17:54:29

Sorting by multiple fields in one comparator?

There is an example of a comparator. How to make it work for all fields of the class? (selectively, so as not to write your own comparator for each field)

public class Book
  {
    private string name;
    private string author;
    private int releaseDate;
    
    public int CompareTo(Book book)
    {
      if (book != null)
      {
        return name.CompareTo(book.name);
      }
      else
      {
        throw new Exception("Невозможно сравнить два объекта");
      }
    }
  }

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Mercury13, 2017-09-29
@Basil_Dev

Didn't understand. If one by one, if equal - by another, if still equal - by the third, then something like this.

public int CompareTo(Book book)
    {
      if (book != null)
      {
        int r = name.CompareTo(book.name);
        if (r != 0)
          return r;
        r = author.CompareTo(book.author);
        if (r != 0)
          return r;
        return Math.sign(releaseDate - book.releaseDate);
      }
      else
      {
        throw new Exception("Невозможно сравнить два объекта");
      }
    }

If you want, depending on some settings, to sort either by name or by author, make a collection of objects of different types.
const int NAME = 0, AUTHOR = 1, COUNT = 2;

class ByName : Comparer<Book> {}
class ByAuthor : IComparer<Book> {}

Comparer<Book> comparers[COUNT] = {  new ByName(), new ByAuthor() };

I don't know C# well, syntax errors are possible.
The third option is to make uniform access for fields of the same types.
const int S_NAME = 0, S_AUTHOR = 1, S_COUNT = 2;
const int I_DATE = 0;

public class Book
{
    string stringFields[S_COUNT];
    int intFields[I_COUNT];

    public string name {
        get { return stringFields[S_NAME; ] }
        set { stringFields[S_NAME] = value; }
    }
}

class StringComparer : IComparer<Book> {
   int code;
   StringComparer(int aCode) { code = aCode; }
   int Compare(Book a, Book b) { return a.stringFields[code].compareTo(b.stringFields[code]); }
}

const int ALL_NAME = 0, ALL_AUTHOR = 1, ALL_DATE=2, ALL_COUNT = 3;

Comparer<Book> comparers[ALL_COUNT] = {  
   new StringComparer(S_NAME), new StringComparer(S_AUTHOR), new IntComparer(I_DATE) };

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question