Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

array => hash of occurrence indexes

by pldanutz (Acolyte)
on Sep 11, 2013 at 10:53 UTC ( #1053457=perlquestion: print w/ replies, xml ) Need Help??
pldanutz has asked for the wisdom of the Perl Monks concerning the following question:

Better / shorter ways to write this? It takes a list and returns a hash of arrays (key => list of indices where key appears in argument)
use 5.012; use warnings; use Data::Dumper; sub occurrences { my %h; while (my ($i, $k) = each (@_)) { if (! $h {$k}) { $h {$k} = [] } push $h {$k}, $i } return %h } my %h = occurences (2, 1, 3, 4, 3, 4, 4, 5 ); print Dumper (\%h)'

Comment on array => hash of occurrence indexes
Download Code
Re: array => hash of occurrence indexes
by BrowserUk (Pope) on Sep 11, 2013 at 11:17 UTC

    Not so much shorter, but avoids the 5.12 dependency:

    sub occurs{ my %h; push @{ $h{ $_[$_] } }, $_ for 0 .. $#_; return \%h };; pp occurs( 2, 1, 3, 4, 3, 4, 4, 5 );; { 1 => [1], 2 => [0], 3 => [2, 4], 4 => [3, 5, 6], 5 => [7] }

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
    /blockquote
Re: array => hash of occurrence indexes
by choroba (Abbot) on Sep 11, 2013 at 11:20 UTC
    Pushing to the $i? That is a bit too much for 5.12.
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Fixed. Didn't copy/paste from the right source.
        Please, mark changes to the original IN the original... and include a note that the post has been updated, in the post. Do NOT delete/replace; use strikeouts.
Re: array => hash of occurrence indexes
by kcott (Abbot) on Sep 12, 2013 at 05:19 UTC

    G'day pldanutz,

    I generally think it's better to pass around scalars than entire data structures, so returning a reference to that hash would be my preference.

    If you wrapped $h{$k} in @{...}, you could dispense with if (! $h {$k}) { $h {$k} = [] } entirely.

    Even if you're using 5.012 for other reasons elsewhere in your code, I see little, if any, value in using each here. It's easy to write it for any Perl5.

    Putting all that together, you could code occurrences() like this instead:

    sub occurences { my %h; my $i = 0; push @{$h{$_}}, $i++ for @_; return \%h; }

    If you were looking for a golf answer, you could start with the following and then proceed to remove whitespace until illegibility was achieved. :-)

    sub occurences { my ($i, %h) = 0; push @{$h{$_}}, $i++ for @_; \%h }

    Here's my tests:

    $ perl -Mstrict -Mwarnings -e ' use Data::Dumper; sub occurences { + my %h; my $i = 0; push @{$h{$_}}, $i++ for @_; return \%h; } my $h = occurences(2, 1, 3, 4, 3, 4, 4, 5); print Dumper $h; ' $VAR1 = { '1' => [ 1 ], '3' => [ 2, 4 ], '2' => [ 0 ], '4' => [ 3, 5, 6 ], '5' => [ 7 ] };
    $ perl -Mstrict -Mwarnings -e ' use Data::Dumper; sub occurences { my ($i, %h) = 0; push @{$h{$_}}, $i++ for @_; \%h + } my $h = occurences(2, 1, 3, 4, 3, 4, 4, 5); print Dumper $h; ' $VAR1 = { '4' => [ 3, 5, 6 ], '1' => [ 1 ], '5' => [ 7 ], '2' => [ 0 ], '3' => [ 2, 4 ] };

    -- Ken

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (10)
As of 2014-12-28 21:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (183 votes), past polls