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