Search code examples
c#linqlambda

order the list based on a condition


I want to order a lambda result . I did this:

   var dicWords= _context.dicWords
    .Select(p=>new WordsDicDto
    {
      Id=p.Id,
      OrderingLetter=p.OrderingLetter,
      Word=p.Word,
    })                              
   .ToList();

I want to order the list by this condition. if the OrderingLetter is numeric it should be ordered by int.parse(p.OrderingLetter) and if it is not numeric so it should ordered by p,OrderingLetter itself. how should accomplish that?


Solution

  • If I understand your question right, you are looking for something like shown below. The most important place is the CompareTo() method which defines which order two elements have to each other. A negative value means that the current instance (accessed by this.) is preceding obj in sort order. Positive means the opposite. (See also here for the official documentation for CompareTo(): https://learn.microsoft.com/en-us/dotnet/api/system.icomparable.compareto?view=net-6.0#returns)

    var dicWords = new List<WordsDicDto>(){
        new WordsDicDto() {Id = "1", OrderingLetter = "M", Word = "Mouse" },
        new WordsDicDto() {Id = "3", OrderingLetter = "2", Word = "Bycicle"},
        null,
        new WordsDicDto() {Id = "4", OrderingLetter = "1", Word = "Dog"},
        new WordsDicDto() {Id = "2", OrderingLetter = "C", Word = "Car"},
    };
    
    Console.WriteLine("The words before sorting:");
    dicWords.ForEach(p => Console.WriteLine($"{p?.Id} | {p?.OrderingLetter} | {p?.Word}"));
    
    // This is the filtering
    var result = dicWords.OrderBy<WordsDicDto, object>(p => p).ToList();
    
    Console.WriteLine("--");
    Console.WriteLine("The words after sorting:");
    result.ForEach(p => Console.WriteLine($"{p?.Id} | {p?.OrderingLetter} | {p?.Word}"));
    

    This is the used implementation of WordsDicDto with the implementation of CompareTo():

    internal class WordsDicDto : IComparable
    {
        public string Id { get; set; }
        public string OrderingLetter { get; set;}
        public string Word { get; set; }
    
        public int CompareTo(object obj)
        {
            if (obj is WordsDicDto p)
            {
                if (int.TryParse(this.OrderingLetter, out int instanceValue) &&
                    int.TryParse(p.OrderingLetter, out int numericValue))
                {
                    return instanceValue - numericValue;
                }
                else
                {
                   return String.Compare(this.OrderingLetter, p.OrderingLetter, StringComparison.Ordinal);
                }
            }
            else
            {
                return -1;
            }
        }
    }