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

Can anyone explain the codes below?

# Code1 @s = sort mycriteria @a; sub mycriteria { my($aa) = $a =~ /(\d+)/; my($bb) = $b =~ /(\d+)/; sin($aa) <=> sin($bb) || $aa*$aa <=> $bb*$bb; }
# Code2 @s = sort {($a =~ /(\d+)/)[0] <=> ($b =~ /(\d+)/)[0] || uc($a) cmp uc( +$b)} @a;

How the regular expressions function in the code above??

Replies are listed 'Best First'.
Re: Questions on sort
by ikegami (Patriarch) on Aug 16, 2011 at 05:46 UTC
    They extract numbers from the strings to compare.
    >perl -E"my ($aa) = 'abc123def' =~ /(\d+)/; say $aa;" 123 >perl -E"say( ('abc123def' =~ /(\d+)/)[0] );" 123

      what is the purpose of putting the "[0]" in the second code? I got the same output with the "[0]" removed.

      >perl -E "say('abc123def' =~ /(\d+)/);" 123

        In the code ($a =~ /(\d+)/)[0] <=> ($b =~ /(\d+)/)[0] the regular expression is used in a list slice with a single index which returns a scalar value which can be compared with the <=> operator.    Without the list slice the regular expression would return TRUE or FALSE in scalar context.

        In the code my($aa) = $a =~ /(\d+)/; the parentheses around $aa impose list context on the regular expression which in list context returns all the contents of capturing parentheses in the regular expression.

        The original code didn't use say, though. It used something that placed the expression scalar context, and there it makes a difference.

        >perl -E"say(scalar( 'abc234def' =~ /(\d+)/ ));" 1 >perl -E"say(scalar( ('abc234def' =~ /(\d+)/)[0] ));" 234
        Its the same purpose they would serve in an array
        print( ( 4,6,8 )[0] )
Re: Questions on sort
by jiashiun (Initiate) on Aug 20, 2011 at 09:23 UTC

    Thanks a lot! i got it now =)