Home > database >  order the list based on a condition
order the list based on a condition

Time:07-31

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?

CodePudding user response:

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://docs.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;
        }
    }
}

CodePudding user response:

You can write a conditional OrderBy

var dicWords = _context.dicWords
    .Select(p => new WordsDicDto
    {
      Id = p.Id,
      OrderingLetter = p.OrderingLetter,
      Word = p.Word,
    })      
    .OrderBy(a =>
    {
        if (int.TryParse(a.OrderingLetter, out int orderingLetter))
        {
            return orderingLetter;
        }
        return 0;//Default order
    })                       
   .ToList();
  • Related