Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

keys with an expression

by morgon (Deacon)
on Nov 20, 2013 at 09:47 UTC ( #1063494=perlquestion: print w/ replies, xml ) Need Help??
morgon has asked for the wisdom of the Perl Monks concerning the following question:

Hi

this is a way to get the unique elements of an array:

my @array = (1,1,2,3,2,2); my %temp = map { $_ => 1 } @array; my @unique = keys %temp;
I would like to do away with the temporary hash and would like to write the following seemingly natural perl-code:

my @unique = keys (map { $_ => 1 } @array);
But to my amazement this does not work with 5.18.1 - the error is "Type of argument to keys on reference must be unblessed hashref or arrayref".

I could swear this used to work some years ago (not really sure), so my question is how can I do this - how can I use keys with such an expression?

Is there really no way to avoid the ugly temporary?

Please note that the above is just an illustration - this is not a question about how to find unique array elements but a question concerning the kinds of expressions I can feed into keys.

Comment on keys with an expression
Select or Download Code
Replies are listed 'Best First'.
Re: keys with an expression
by hdb (Prior) on Nov 20, 2013 at 09:49 UTC

    This should work in the newer Perls:

    my @unique = keys { map { $_ => 1 } @array };
Re: keys with an expression (List::AllUtils::uniq
by Anonymous Monk on Nov 20, 2013 at 10:08 UTC

    create a hash,ref { }

    dereference same hash,ref %{ { } }

    keys likes it

    use Data::Dump; dd( keys %{{ map { $_,1 } 1,2,1,2,1,4 }} ); __END__ (4, 1, 2)

    List::AllUtils :)

Re: keys with an expression
by tobyink (Abbot) on Nov 20, 2013 at 12:57 UTC

    This does create a temporary hash, but avoids the need to choose a name for the hash:

    my @items = qw( foo bar bar baz quux baz ); my @unique = local(*_) && grep(!$_{$_}++, @items); print "$_\n" for @unique;
    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
Re: keys with an expression
by lune (Monk) on Nov 20, 2013 at 15:04 UTC
    I don't know if that worked before, but I do find the error message okay, as
    (map { $_ => 1 } @array)
    returns a list, not an array, which "keys" would also accept as a valid argument.

    You get the same error if you try:

    my @unique = keys (1,1,2,3,2,2);

    but not with:
    my @unique = keys @array;
    which returns the indices of the array.
Re: keys with an expression
by AnomalousMonk (Abbot) on Nov 20, 2013 at 19:16 UTC
    ... this is ... a question concerning the kinds of expressions I can feed into keys.

    Answers to questions like this can be had by Reading about keys and other, er, keywords (and much else besides) in The Fine Manual(s). (And BTW: Feeding keys et al a hash/array reference works from 5.14 on.)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1063494]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (7)
As of 2015-08-29 08:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The oldest computer book still on my shelves (or on my digital media) is ...













    Results (343 votes), past polls