Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort List<T> in c#

Tags:

I've got a List<Card>, and I want to sort these cards

So, I'm looking for a method to sort them with different criterias, like their ID, their Name ...

public class Card : IComparer
{
    public string ID;
    public string Name;
    public int CompareId(object firstCard, object secondCard) 
    {
        Card c1 = (Card)firstCard;
        Card c2 = (Card)secondCard;
        return c1.Id.CompareTo(c2.Id);
    }
}

But then, visual studio sent me an error :

'Card' does not implement interface member 'IComparer<Card>.Compare(Card, Card)'

like image 676
Erito Avatar asked Aug 06 '19 07:08

Erito


People also ask

Can you sort a list C#?

Sorting in C# In C#, we can do sorting using the built-in Sort / OrderBy methods with the Comparison delegate, the IComparer , and IComparable interfaces.

Does the sort () method modify the underlying list?

Yes the List<T>. Sort method does indeed sort the collection in place and hence modifies the collection.

How do you sort elements in C#?

The simplest way to sort an array in C# is using Array. Sort method. The Array. Sort method takes a one-dimensional array as an input and sorts the array elements in the ascending order.


2 Answers

You, probably, want to have your class Comparable not a Comparator

public class Card : IComparable<Card>
{
    public string ID;
    public string Name;

    public int CompareTo(Card other) 
    {
        if (null == other)
            return 1;

        // string.Compare is safe when Id is null 
        return string.Compare(this.Id, other.Id);
    }
}

then

List<Card> myList = ...

myList.Sort();

Edit: If you want to have several criteria to choose from, you have to implement several Comparers as separated classes, e.g.

public sealed class CardByIdComparer : IComparer<Card> 
{
    public int Compare(Card x, Card y) 
    {
        if (object.ReferenceEquals(x, y))
            return 0;
        else if (null == x)
            return -1;
        else if (null == y)
            return 1;
        else
            return string.Compare(x.Id, y.Id);
    }
}

and when sorting provide the required:

List<Card> myList = ...

myList.Sort(new CardByIdComparer());

Edit 2: (inspired by spender's library). If you want to combine several comparers into one (i.e. use comparer1, on tie - comparer2 etc.)

public sealed class ComparerCombined<T> : IComparer<T> {
  private IComparer<T>[] m_Comparers;

  public ComparerCombined(params IComparer<T>[] comparers) {
    if (null == comparers)
      throw new ArgumentNullException(nameof(comparers));

    m_Comparers = comparers
      .Select(item => item == null ? Comparer<T>.Default : item)
      .Where(item => item != null)
      .Distinct()
      .ToArray();
  }

  public int Compare(T x, T y) {
    if (object.ReferenceEquals(x, y))
      return 0;
    else if (null == x)
      return -1;
    else if (null == y)
      return 1;

    foreach (var comparer in m_Comparers) {
      int result = comparer.Compare(x, y);

      if (result != 0)
        return result;
    }

    return 0;
  }
}

usage:

myList.Sort(new ComparerCombined(
  new CardByIdComparer(),   // Sort By Id
  new CardByNameComparer()  // On tie (equal Id's) sort by name
));
like image 151
Dmitry Bychenko Avatar answered Sep 22 '22 17:09

Dmitry Bychenko


The easiest way You can use Linq:

List<Card> objSortedList = objListObject.OrderBy(o=>o.ID).ToList();

or

List<Card> objSortedList = objListObject.OrderByDescending(o=>o.ID).ToList();
like image 42
Hardik Masalawala Avatar answered Sep 25 '22 17:09

Hardik Masalawala