Miha Radej wrote:
I have an array of filenames, ie:
@files_a = qw(file1a.ext file1.ext file1m.ext file1g.ext)
@files_b = qw(file2w.ext file2a.ext file2z.ext file2b.ext file2.ext file2x.ext file2y.ext file2c.ext)

What I need to is sort the arrays by the versions (the files I have been presented with use alphabetical versioning, ie. no letter means original, then versions go as a, b, c, ...).
...


During the heady days of the space race NASA were stumped by the problem of making a fountain pen work in outer space. They spent millions of dollars developing the predecessor of the ball point pen.

The Russians used pencils.

Moral: Sometimes, you're looking at the wrong problem...

Have you considered asking the users to use a numeric sequenceon the files?


...
The problem I have is when instead of an array @files_a I get one like @files_v, which contains letters from the end of the alpahbet and the beginning, which should mean that the users ran out of letters and began from a, b, ... again.
...

I don't get why they'd start a sequence halfway through the alphabet... I assume that there is never more than 23 parts to the file (22 alpha's + the base).


...

The desired sort order would be something like:
- first the file without the version letter, ie. ends with a number (if it exists)
- then a-z
...

@newarray = sort @oldarray; '.' (0x2e) will sort before 'a' (0x61) so that seems pretty simple.

...
In case of @files_b like arrays:
- first the file without the version letter (if it exists)
- then versions from the last part of the alphabet
- versions from the first part of the alphabet

...

If you create an index array of your valid alphabet (I see from one of your other messages that you have a non-standard alphabet which is a nasty twist for some algorithms).

Create a hash of the filenames, putting aside the basefilename so it doesn't confuse things.

Define two arrays, one for the characters at the start of the alphabet and the other for the characters from the end.

Use the index array to step though the hash keys looking for the end of the low order characters putting them in the tail array and then scan forward to the start of the high order chars, adding those to the head array. (Who'd know english is my first language? It's easier to express in code).

Merge the basename, head and tail arrays into a custom sorted array and you're done.

See code below for a quick stab at how it could be done...

...

There can be "holes" in versions (ie. a, b, e, f) but not very likely. The versionless files often do not exist but I need to take them into consideration in case if they do.

If you are referring to the q,w,x,y then that's handled by the custom alphabet index. If you mean there are holes in the sequence, then how can you decide whether j,k,l,r,s,t should be ordered as rstjkl or jklrst? It's madness...



Here's how I think you can solve the problem right up to the holes in the sequence...

Cheers

Steve


#!/usr/local/bin/perl
@files_b = qw/
        file2s.ext file2a.ext file2t.ext
        file2b.ext file2.ext file2u.ext
        file2v.ext file2c.ext file2z.ext/;

#build an array of our alphabet
@halfabet = qw/a b c d e f g h i j k l m n o p r s t u v z/;

for(@files_b){
  if(m/\d(.)\.ext$/){
    $files{$1} = $_; #add files to a hash keyed by sequence letter
  }else{
    $base_file = $_;  #set aside basefilename
  }
}
$tailing = 1;           #flag so we know which list we're building
for (@halfabet){        #iterate through the sort index
  if ($tailing){                                
    if(defined $files{$_}){     #ignore the unused letters
      push @tail,$files{$_};    #add to the tail list a,b,c
    }else{
      $tailing = 0;      #until we hit the end of the first list
    }
  }else{
     if(defined $files{$_}){   #continue adding the remaining files
      push @head,$files{$_};            # to the head list x,y,z
    }
  }
}
#reassemble the basename, head and tail lists base,x,y,z,a,b,c
@sorted = ($base_file,@head,@tail);

_______________________________________________
Perl-Win32-Users mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to