On DALnet #perl this morning, someone was asking how to use sort() to sort only so far as to get elements containing "gnome/" and "session" to the front, and such that "gnome/" elements preceed "session" elements. I said he wanted a sifting-like function, not a sorting one. I came up with three, and benchmarked them. My first attempt: # orig_sift(\@list, qr/RE/, qr/RE/, ...) sub orig_sift { my ($aref,$i) = (shift,0); my %pos = map { ($_, $i++) } @_; my @ret; ELEMENT: for (@$aref) { for my $re (@_) { push(@{ $ret[$pos{$re}] }, $_), next ELEMENT if $_ =~ $re; } push @{ $ret[$i] }, $_; } return map @$_, @ret; } Then I thought I could beef it up with eval (I was wrong). Then someone tried using grep, but they made it rather inefficiently: grep(/ALPHA/, @list), grep(/BETA/,@list), grep(!/ALPHA|BETA/,@list) I pointed out it goes through the WHOLE list each time, so I offered this: sub grep_sift { my @sifted = (); my @list = @{ shift() }; for my $re (@_) { my @normal; push @sifted, grep { ($_ =~ $re) ? 1 : do { push(@normal, $_), 0 } } @list; @list = @normal; } return (@sifted,@list); } The results of benchmarks and code are at: http://www.pobox.com/~japhy/DALnet-perl/ -- MIDN 4/C PINYAN, NROTCURPI, US Naval Reserve japhy@pobox.com http://www.pobox.com/~japhy/ http://pinyaj.stu.rpi.edu/ PerlMonth - An Online Perl Magazine http://www.perlmonth.com/ The Perl Archive - Articles, Forums, etc. http://www.perlarchive.com/ ==== Want to unsubscribe from Fun With Perl? Well, if you insist... ==== Send email to <fwp-request@technofile.org> with message _body_ ==== unsubscribe