First, this is not about the standard answer about inverting a hash using 'reverse' and how non-unique values clobber each other in the new hash. I'm writing about efficiency. I frequently find myself using code that looks like this:
sub invert { my $x = shift; my $y = {}; foreach my $xk1 (keys %$x) { foreach my $xk2 (keys %{$x->{$xk1}}) { $y->{$xk2}{$xk1} = $x->{$xk1}{$xk2}; } } return $y; }
Basically, I'm just rearranging a hash, for example, if I have a hash of 'days' of 'hours' of 'something', and I want to rearrange into 'hours' of 'days' of something. Is there a better/more perly way to do this? A function call to a c-compiled call? Something that does not require foreaches to essentially claw through every element in perl. I'm doing this a lot, on some very large data structures. It's not particularly slow, but still... Also, I'm trying to minimize unecessary copying. The code above at least only copies references, if that's what exist past the first two levels, but no copying at all would be best.

In reply to Invert a hash... not a FAQ (I hope) by djacobow

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.