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

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

Hi, This is a crosslist from stack overflow The problem is the following
use strict; use List::MoreUtils qw/uniq/; use Data::Dumper; my @x = (3,2); my @y = (4,3); print "unique results \n"; print Dumper([uniq(@x,@y)]); print "sorted unique results\n"; print Dumper([sort uniq(@x,@y)]);
gives as output
unique results $VAR1 = [ 3, 2, 4 ]; sorted unique results $VAR1 = [ 2, 3, 3, 4 ];

Unfortunately the uniq does not work anymore.
There is an answer from amon that perl uses the sort function form where the first parameter is a function and the second a list, but i still don't understand why it does not execute uniq beforehand and then uses the sort LIST,instead of preferring the sort SUBNAME LIST form.

Amon also suggested to use
sort +uniq @letters;
What does the + mean?
Thanks,
David

Replies are listed 'Best First'.
Re: why does sort with uniq not work together
by tobyink (Canon) on Nov 27, 2013 at 12:51 UTC

    The + is the unary plus operator. It does nothing, but can be used to disambiguate a first argument. For example:

    print (1 + 2) . "\n";

    You might expect that to be roughly the same as print "3\n", but it's actually more like my $tmp = print 3; $tmp . "\n". The line break doesn't get printed; it gets concatenated to the return value of the print function. That is, it's parsed like:

    (print(1+1)) . "\n";

    The unary plus helps Perl notice that something is an argument to the preceding function:

    print +(1 + 2) . "\n";

    Unary plus can also be useful in disambiguating +{} (a hashref) from { } (an empty block of code).

    See Symbolic Unary Operators in perlop.

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
Re: why does sort with uniq not work together
by 2teez (Vicar) on Nov 27, 2013 at 12:58 UTC

    Hi david2008,
    If you use warnings; you would have seen this message: Sort subroutine didn't return single value at line ...
    so using this

    print "sorted unique results\n"; print Dumper( [ sort( uniq( @x, @y ) ) ] );
    would resolve the issue. Try it

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me

      Yes, but why?

        Hi hdb,
        Yes, but why?
        Checking sort documentation you will find this:

        Warning: syntactical care is required when sorting the list returned from a function. If you want to sort the list returned by the function call "find_records(@key)", you can use:
        @contact = sort { $a cmp $b } find_records @key; @contact = sort +find_records(@key); @contact = sort &find_records(@key); @contact = sort(find_records(@key));
        Among other things..
        That shows it can as well use: print Dumper( [ sort &uniq( @x, @y )  ] ); showing the list to be sorted is returned from a function.

        If you tell me, I'll forget.
        If you show me, I'll remember.
        if you involve me, I'll understand.
        --- Author unknown to me
Re: why does sort with uniq not work together
by choroba (Cardinal) on Nov 27, 2013 at 13:13 UTC
    why it does not execute uniq beforehand
    But it does, it executes uniq as the function that tells sort how to compare elements, as in
    sort { uniq($a, $b) } @x, @y;
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Looks like it :)

      $ perl -le " sub uniq {warn++$q;@_} print for sort uniq(1,8,4,3) " 1 at -e line 1. 2 at -e line 1. 3 at -e line 1. 4 at -e line 1. 1 8 4 3 $ perl -MO=Deparse -le " sub uniq {warn++$q;@_} print for sort uniq(1, +8,4,3) " BEGIN { $/ = "\n"; $\ = "\n"; } sub uniq { warn ++$q; @_; } print $_ foreach (sort uniq 1, 8, 4, 3); -e syntax OK