Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort a list by namespaces

Tags:

c#

list

sorting

I would like some help sorting a specific list.

Imagine the following list:

antennas.sequence
antennas.ports
antennas.1.power
antennas.2.power
antennas.found
radio.modulation.1.set
radio.modulation.2.set
radio.transmit
radio.frequency

If we applied the simple List.Sort() function it will become like this:

antennas.1.power
antennas.2.power
antennas.found
antennas.ports
antennas.sequence
radio.frequency
radio.modulation.1.set
radio.modulation.2.set
radio.transmit

But I'm looking for a sort that will respect the number of namespaces, so the items with less depth should be on top of each other. For the above example I expect the list to be sorted like this:

antennas.found
antennas.ports
antennas.sequence
antennas.1.power
antennas.2.power
radio.frequency
radio.transmit
radio.modulation.1.set
radio.modulation.2.set
like image 418
tvborda Avatar asked Nov 21 '25 03:11

tvborda


1 Answers

I'm sure there is a more elegant way to do this, However...

Given Extensions

public static IOrderedEnumerable<string[]> RecusiveCustomOrderBy(this IOrderedEnumerable<string[]> list,int maxDepth, int depth = 1)
{
   if (depth >= maxDepth)
      return list;

   return list.ThenBy(x => x.Length <= depth ? null : x[depth])
              .ThenBy(x => x.Length)
              .RecusiveCustomOrderBy(maxDepth, depth + 1);
}

public static List<string> NamespaceOrderBy(this List<string> list)
{
   var split = list.Select(x => x.Split('.')).ToList();
   var maxDepth = split.Max(x => x.Length);

   return split.OrderBy(x => x[0])
               .ThenBy(x => x.Length)
               .RecusiveCustomOrderBy(maxDepth)
               .Select(x => string.Join(".", x))
               .ToList();
}

Usage

var list = new List<string>
   {
      "antennas.sequence",
      "antennas.ports",
      "antennas.1.power",
      "antennas.2.power",
      "antennas.found",
      "radio.modulation.1.set",
      "radio.modulation.2.set",
      "radio.transmit",
      "radio.frequency"
   };

var results = list.NamespaceOrderBy();

Output

antennas.found
antennas.ports
antennas.sequence
antennas.1.power
antennas.2.power
radio.frequency
radio.transmit
radio.modulation.1.set
radio.modulation.2.set

Full Demo Here

Note : It can probably do with some simple error checking

like image 172
TheGeneral Avatar answered Nov 22 '25 17:11

TheGeneral



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!