Home > Software design >  Order list by date and sequence number
Order list by date and sequence number

Time:03-25

I have been learning C# (I am relatively new) and I have a list of input files consisting file naming format like "inputFile_dateSequence_sequenceNumber.xml". The code that I am using to sort the file lists in ascending order is below:

using System;
using System.Collections.Generic;
using System.Linq;
                    
public class Program
{
    public static void Main()
    {
        string[] inputfiles = { "inputFile_2020-04-10_1.xml", 
                               "inputFile_2020-04-10_2.xml", 
                               "inputFile_2020-04-10_4.xml",
                               "inputFile_2020-04-10_3.xml", 
                               "inputFile_2020-04-10_10.xml",
                               "inputFile_2020-05-10_1.xml",
                               "inputFile_2020-05-10_2.xml",
                               "inputFile_2020-05-10_10.xml",
                               "inputFile_2020-05-10_11.xml" };
        
        
        List<string> stringList = new List<string>();
        
        foreach (string s in inputfiles)
        {
            string bz = s.Split('.')[0];
            stringList.Add(bz);
        }
        
        string[] Separator = new string[] { "_" };
        var sortedList = stringList.OrderBy(i => i).ThenBy(s => int.Parse(s.Split(Separator, StringSplitOptions.None)[2])).ToList();
        
        foreach (string i in sortedList)
        {
            Console.WriteLine(i);
        }
        
    }

}

But in ascending order, I am getting output as below:

inputFile_2020-04-10_1
inputFile_2020-04-10_10
inputFile_2020-04-10_2
inputFile_2020-04-10_3
inputFile_2020-04-10_4
inputFile_2020-05-10_1
inputFile_2020-05-10_10
inputFile_2020-05-10_11
inputFile_2020-05-10_2

but my desired output is like below:

inputFile_2020-04-10_1.xml 
inputFile_2020-04-10_2.xml
inputFile_2020-04-10_3.xml
inputFile_2020-04-10_4.xml
inputFile_2020-04-10_10.xml
inputFile_2020-05-10_1.xml
inputFile_2020-05-10_2.xml
inputFile_2020-05-10_10.xml
inputFile_2020-05-10_11.xml

What modification should the code need in order to get the output like this?

CodePudding user response:

You could achieve your need by using regex:

var sortedList= stringList.OrderBy(x => Regex.Replace(x, @"\d ", m => m.Value.PadLeft(10, '0')));

CodePudding user response:

Loads of ways to solve this, as you can see...

You can order first by just the date part of the name, then by the length of the name string, so smaller numbers like 1, 7 sort before longer numbers like 10, 17.. then by the name itself

.OrderBy(x => x.Remove(20))
  .ThenBy(x=>x.Length)
  .ThenBy(x=>x)

Perhaps though you'd parse the entire thing:

class MyFile{
  string FullName {get;set;}
  string Name {get;set;}
  DateTime Date {get;set;}
  int Num {get;set;}

  MyFile(string fullname){
    var bits = Path.GetFilenameWithoutExtension( fullname).Split('_');

    FullName = FullName;
    Name = bits[0];
    Date = DateTime.Parse(bits[1]);
    Num = int.Parse(bits[2]);
  }

Then

var parsed = inputfiles.Select(x => new MyFile(x));

Now you can OrderBy that:

parsed.OrderBy(m => m.Date).ThenBy(m => m.Num);

Try to avoid doing everything at some base level of string/int primitive; this is OO programming!

  • Related