C# Sort files by natural number ordering in the name?

后端 未结 7 1123
刺人心
刺人心 2020-12-03 18:09

I have files in directory like that

0-0.jpeg
0-1.jpeg
0-5.jpeg
0-9.jpeg
0-10.jpeg
0-12.jpeg

....

when i loading files:



        
7条回答
  •  生来不讨喜
    2020-12-03 18:57

    You filenames appear to be structured. If you just sort them, they sort as ordinary strings. You need to:

    1. Parse the file name into its constituent component parts.
    2. Convert the numeric segments to a numeric value.
    3. Compare that structure in the desired order to get the intended collation sequence.

    Personally, I'd create a class that represented the structure implicit in the filename. Perhaps it should wrap the FileInfo. The constructor for that class should parse the filename into its constituent parts and instantiate the properties of the class appropriately.

    The class should implement IComparable/IComparable (or you could create an implementation of Comparer).

    Sort your objects and they should then come out in the collating sequence you desire.

    If looks like your file names are composed of 3 parts:

    • a high-order numeric value (let's call it 'hi'),
    • a low-order numeric value (let's call it 'lo'),
    • and an extension (let's call it 'ext')

    So your class might look something like

    public class MyFileInfoWrapper : IComparable,IComparable
    {
      public MyFileInfoWrapper( FileInfo fi )
      {
        // your implementation here
        throw new NotImplementedException() ;
      }
    
      public int    Hi         { get ; private set ; }
      public int    Lo         { get ; private set ; }
      public string Extension  { get ; private set ; }
    
      public FileInfo FileInfo { get ; private set ; }
    
      public int CompareTo( MyFileInfoWrapper other )
      {
        int cc ;
        if      ( other   == null     ) cc = -1 ;
        else if ( this.Hi <  other.Hi ) cc = -1 ;
        else if ( this.Hi >  other.Hi ) cc = +1 ;
        else if ( this.Lo <  other.Lo ) cc = -1 ;
        else if ( this.Lo >  other.Lo ) cc = +1 ;
        else                            cc = string.Compare( this.Extension , other.Extension , StringComparison.InvariantCultureIgnoreCase ) ;
        return cc ;
      }
    
      public int CompareTo( object obj )
      {
        int cc ;
        if      ( obj == null              ) cc = -1 ;
        else if ( obj is MyFileInfoWrapper ) cc = CompareTo( (MyFileInfoWrapper) obj ) ;
        else throw new ArgumentException("'obj' is not a 'MyFileInfoWrapper' type.", "obj") ;
        return cc ;
      }
    
    }
    

提交回复
热议问题