Home > database >  how can i order multiple digit string integers numerically and by shortest first? C#
how can i order multiple digit string integers numerically and by shortest first? C#

Time:04-11

i have an entity saved on the database that has 2 relevant properties, Code and Number.

the number is just an int between 1 and 99, while the code is a string representation like "01" to "99"

the problem is that some sub-entities have a code like "0103" or "3301", which is just the parent's code it's own code.

all entities are saved on one table, there are 3 levels of hierarchy indicated only by the length of the code "00" is a level 1, "0000" is level 2, and "000000" is level 3.

I want to order them in such a way that they're presented like

  • name - 01
  • name - 010201
  • name - 0103
  • name - 02
  • name - 0201
  • name - 04

and so on...

where an entity with "01" is first, followed by entities that start with "01" and under each one will be entities that start with "01xx", sort of a tree hierarchy.

note that i'm using EFcore 5, .NET 5, and C# 9

what i have right now is simply

var SearchQuery = _appDbContext.Regions.AsNoTracking().AsQueryable().OrderBy(r => r.Code);

and then i use that query to generate my DTOs

ResultData = await SearchQuery.Select(r => new DTO
                {
                    Id = r.Id,
                    NameCode = r.Name   " - "   r.Code
                }).ToListAsync();

should i use a custom comparer or something else? or does this approach satisfy?

CodePudding user response:

Use IComparable :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication20
{
    class Program
    {
        static void Main(string[] args)
        {

            string[] array = {"name - 01", "name - 010201", "name - 0103", "name - 02", "name - 0201", "name - 04"};
            string[] sorted = array.Select(x => new Sort(x)).OrderBy(x => x).Select(x => x.numericStr).ToArray();
        }
    }
    public class Sort : IComparable<Sort>
    {
        public string numericStr { get; set; }
        string[] split { get; set; }
        string number { get; set; }
        public Sort(string input)
        {
            numericStr = input;
            split = input.Split(new char[] { ' ' }).ToArray();
        }
        public int CompareTo(Sort other)
        {
            int minSize = Math.Min(split.Length, split.Length);
            for(int i = 0; i < minSize; i  )
            {
                int c = split[i].CompareTo(other.split[i]);
                if (c != 0) return c;
            }
            return split.Length.CompareTo(other.split.Length);

        }
    }
    
}

CodePudding user response:

I managed to make a function that collects level 1, 2, 3 entities in 3 different Lists (after applying filters) then looping through it less than a couple of times and inserting them to a List<Entity> according to the correct order

but @CharlesMager has clarified to me that the normal OrderBy(r => r.Code) will have the exact same result due to the Code property not having any whitespaces.

in other words: OrderBy(r => r.Code) will NOT sort the string in 01, 02, 01xx as I previously thought; Rather it'll sort them in correct order such as 01, 01xx, 02, 02xx and so on.

  • Related