Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
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 (Canon) 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:

    -- 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 avoiding work at the Monastery: (17)
As of 2015-07-01 15:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (6 votes), past polls