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

Hi Monks
I'm having a issue here where I need to sort the values of the variables in my code here but the sorting is getting done on the letter values and not after the reg. exp. changes to what I want them to.
Here is what I am trying to say:
$status=~s/P|F|C|D|I/Posted/g; $status=~s/A/Accepted/g; $status=~s/N/New/g; $status=~s/R/Rejected/g; $status=~s/S/Save/g; $status=~s/X/Canceled/g; my @strings = $status; my @sorted_strings = sort @strings; print "<br><font color=red>@sorted_strings</font><br>";

I want to sort after all the single letter has been changed to the corresponded values on the regular expression.
Thanks for the help!

Replies are listed 'Best First'.
Re: Sorting Issue
by davorg (Chancellor) on Jul 26, 2005 at 13:48 UTC

    I think you may be not showing us something important. It looks to me as though you are assigning a scalar value ($status) to an array (@strings). This makes @strings an array containing one value and therefore the sort will have no effect at all.

    Or am I missing something obvious?

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Sorting Issue
by blazar (Canon) on Jul 26, 2005 at 13:53 UTC
    I'm having a hard time trying to make sense of what you may mean. Your code plainly won't work and IMHO it doesn't shed any light on what your real aim may be.

    here you have a variable to which you apply a series of substitutions, (incidentally it is customary to write

    for ($status) { s/P|F|C|D|I/Posted/g; s/A/Accepted/g; s/N/New/g; s/R/Rejected/g; s/S/Save/g; s/X/Canceled/g; }
    when you have a long series of of substitutions - much cleaner IMHO).

    Update: contrary to what I wrote above, in this particular case I'd probably do something along the lines of (untested):

    my %subst={ A => 'Accepted', N => 'New', R => 'Rejected', S => 'Save', X => 'Canceled' }; $subst{$_}='Posted' for qw/P F C D I/; $status =~ s/[A-Z]/$subst{$&}||$&/ge;

    Note to the update: I am aware of the gotchas about $& & C. My gut feeling is that people overestimate them. Personally I'm not a fanatic of its use, but happen to resort to it every now and again...

    Then you create an array containing only (the value of) that variable and sort it, which is an immaterial operation, since it has only one entry in any case.

      The only part missing is that the value of $status comes from a data base for specific record as P|F|C|D|I|A|N|R|S|X and after that I am using the reg. exp. to translate into a more specific message. I am just trying to display the values sorted.
        All code below is untested

        Update: suggestion about splitting is valid only if the result from database is "|"-separated, as cleverly pointed out here...

        You had to say it immediately:

        my @strings = split /\|/, $status;
        Note that, by default, putting @sorted_strings in double quotes will give you space-separated items. You can change the separator using the perlvar $":
        { local $" = "|"; print "<br><font color=red>@sorted_strings</font><br>"; }
        I put the curly brackets in order to restrict the modification of the $" variable, making this modification "visible" to the print statement only.

        Anyway, I'd probably use a more flexible, metadata-based approach:

        my %subst ( P => 'Posted', F => 'Posted', C => 'Posted', D => 'Posted', I => 'Posted', A => 'Accepted', N => 'New', R => 'Rejected', S => 'Save', X => 'Canceled', ); my @sorted_strings = sort map { $subst{$_} } split /\|/, $status; # The above line can be roughly expanded to the three lines below: # # my @status_letters = split /\|/, $status; # my @strings; # foreach (@status_letters) { # push @strings, $subst{$_} # } # my @sorted_strings = sort @strings;

        Flavio
        perl -ple'$_=reverse' <<<ti.xittelop@oivalf

        Don't fool yourself.
        So far so fine. Care to read the ramining part of my post?

        Turning the glass sphere mode one I guess you may be after something like:

        my @strings; while ( whatever ) { # ... push @strings, $status; } my @sorted=sort @strings;
        $status=~s/P|F|C|D|I/Posted/g; $status=~s/A/Accepted/g; $status=~s/N/New/g; $status=~s/R/Rejected/g; $status=~s/S/Save/g; $status=~s/X/Canceled/g; my @strings = split /\|/, $status; my @sorted_strings = sort @strings; print "<br><font color=red>@sorted_strings</font><br>";

        Update: If there is for each record status is only one letter, then I misunderstood string 'P|F|C|D|I|A|N|R|S|X' and '|' stands for 'or'. In such case see blazar's post.
        while ($pointer = $sth->fetchrow_hashref) { ....code.... $status=~s/P|F|C|D|I/Posted/g; $status=~s/A/Accepted/g; $status=~s/N/New/g; $status=~s/R/Rejected/g; $status=~s/S/Save/g; $status=~s/X/Canceled/g; my @strings = $status; my @sorted_strings = sort @strings; print "<br><font color=red> @sorted_strings</font><br>"; }
Re: Sorting Issue
by trammell (Priest) on Jul 26, 2005 at 18:06 UTC
    Hard to be sure exactly what you are asking, but here's a go:
    #!perl -l use strict; use warnings; my @a = qw/ A C D F I N P R S X /; my @status = map $a[ rand @a ], 1 .. 20; for (@status) { s/P|F|C|D|I/Posted/; s/A/Accepted/; s/N/New/; s/R/Rejected/; s/S/Save/; s/X/Canceled/; } my @strings = sort @status; print for @strings; __END__ Accepted Canceled Canceled Canceled New New New New Posted Posted Posted Posted Posted Posted Posted Posted Posted Rejected Rejected Save
Re: Sorting Issue
by polettix (Vicar) on Jul 28, 2005 at 13:35 UTC
    Ok, from the indentation and the sparse info you give above it seems that you're not telling the whole story here about your code.

    What is unclear is where you get the list of data you have to sort. $status is a scalar, and according to Re^6: Sorting Issue it contains a single letter. What are you trying to sort? The only explaination I can give about this is that you get multiple values from somewhere, so you're not giving the cycle over which you're iterating. However, excercising some powers, we could guess something like this:

    my %subst ( P => 'Posted', F => 'Posted', C => 'Posted', D => 'Posted', I => 'Posted', A => 'Accepted', N => 'New', R => 'Rejected', S => 'Save', X => 'Canceled', ); my @strings; # Note: declared before while ($iteration_condition_is_true) { my $status = gets_some_value(); my $extended_status = $subst{$status}; # Add the string to the list push @strings, $extended_status; } my @sorted_strings = sort @strings;
    So, you have to declare @strings before the cycle, and push each $extended_status you get inside it to have the list you need to perform the sort. Otherwise... you know, sorting a one-element list does not make much sense :)

    Flavio
    perl -ple'$_=reverse' <<<ti.xittelop@oivalf

    Don't fool yourself.