http://www.perlmonks.org?node_id=812198

perlCrazy has asked for the wisdom of the Perl Monks concerning the following question:

Input array is like :
my @arr = ('TEXT1','TEXT11','TEXT13','TEXT2','TEXT3');
How to get new array like this:
my @newArr = ('TEXT1','TEXT2','TEXT3','TEXT11','TEXT13');
i can do like this:
my @arr1; foreach my $val (@arr) { $val =~ s/TEXT//gx; push @arr1, $val; } foreach my $val1 (sort {$a <=> $b} @arr1) { my $text = 'TEXT'.$val1; push @newArr, $text; }
how we can use map here?
Thanks

Replies are listed 'Best First'.
Re: Need help in sorting the array
by johngg (Canon) on Dec 10, 2009 at 14:56 UTC

    You could do it like this using a couple of maps sandwiching a sort.

    $ perl -le ' > @arr = qw{ TEXT1 TEXT3 TEXT11 TEXT2 TEXT13 }; > print for > map { $_->[ 0 ] } > sort { $a->[ 1 ] <=> $b->[ 1 ] } > map { [ $_, ( split m{(?<=[A-Z])(?=\d)} )[ 1 ] ] } > @arr;' TEXT1 TEXT2 TEXT3 TEXT11 TEXT13 $

    I hope this is helpful.

    Cheers,

    JohnGG

Re: Need help in sorting the array
by BioLion (Curate) on Dec 10, 2009 at 14:57 UTC

    You Could use a custom sort routine:

    use warnings; use strict; my @arr = ('TEXT1','TEXT11','TEXT13','TEXT2','TEXT3'); print "BEFORE:\n"; print "\'$_\'\n" for @arr; ## pass code block to sort to control sort behaviour @arr = sort by_numbers @arr; ## look again print "AFTER:\n"; print "\'$_\'\n" for @arr; sub by_numbers{ my $a_num = $a =~ /^TEXT(\d+)$/; my $b_num = $b =~ /^TEXT(\d+)$/; ## maybe also include checking that $a_num and $b_num are defined return ($a_num <=> $b_num); }

    Updated: Typo in code

    Just a something something...
Re: Need help in sorting the array
by keszler (Priest) on Dec 10, 2009 at 14:57 UTC
    my @newArr = sort { (my $aa=$a)=~s/\D//g; (my $bb=$b)=~s/\D//g; $aa <= +> $bb } @arr
Re: Need help in sorting the array
by AnomalousMonk (Archbishop) on Dec 10, 2009 at 20:15 UTC

    From the OP:

    my @arr1; foreach my $val (@arr) { $val =~ s/TEXT//gx; push @arr1, $val; }

    Note that because  $val is aliased in the loop above, the source array  @arr is modified!

    >perl -wMstrict -le "my @source = qw(TEXT1 TEXT11 TEXT13 TEXT2 TEXT3); for my $val (@source) { $val =~ s/TEXT//; } print qq{@source}; " 1 11 13 2 3
Re: Need help in sorting the array
by bv (Friar) on Dec 10, 2009 at 15:06 UTC

    I believe this calls for an application of the GRT (untested):

    my @newArr = map { # put it all back together join '', @$_ } sort { # dereference and sort numerically by 2nd element $a->[1] <=> $b->[1] } map { # break off the digits and put in an anonymous array [ split /(\d+)/ ] } @arr;

    @_=qw; Just another Perl hacker,; ;$_=q=print "@_"= and eval;
      I believe this calls for an application of the GRT (untested):

      Actually, what you have there is a ST (http://en.wikipedia.org/wiki/Schwartzian_transform). A GRT (http://www.sysarch.com/Perl/sort_paper.html) is characterised by having a simple lexical sort rather than requiring a routine. Like this:

      $ perl -le ' > @arr = qw{ TEXT1 TEXT3 TEXT11 TEXT2 TEXT13 }; > print for > map { substr $_, 9 } > sort > map { sprintf q{%09d%s}, ( split m{(?<=[A-Z])(?=\d)} )[ 1 ], $_ +} > @arr;' TEXT1 TEXT2 TEXT3 TEXT11 TEXT13 $

      I hope this is of interest.

      Cheers,

      JohnGG

      Update: Added references.

        I always get those confused! Someday I'll learn, or at least learn to look it up before I post.


        @_=qw; Just another Perl hacker,; ;$_=q=print "@_"= and eval;
        Thanks a lot guys !!! this is hepful