Okay, I get where your going (I think). It work's but carries a fairly high cost.

I was premature in accepting etcshadow's suggestion. When it came to implementing it, the shine fell away.

This details the problem(s) as I see it so far:

Using your technique,

@actual %indexOf @keyFor 0 [ A_value ] { A => 0 } [ A ] 1 [ B_value ] { B => 1 } [ B ] 2 [ C_value ] { C => 2 } [ C ] 3 [ D_value ] { D => 3 } [ D ] 4 [ E_value ] { E => 4 } [ E ]

Accessing C via key calls for C to become top item so calling getByKey( 'C' ); does:

sub getByKey { my $key = shift; my $idx = $indexOf{ $key }; my $value = $actual[ $idx ]; push @actual, splice @actual, $idx, 1; push @keyFor, splice @keyFor, $idx, 1; ## Completely re-build %indexOf $indexOf{ $keyFor[ $_ ] } = $_ for 0 .. $#keyFor; return $value }

Afterwards, all linkages are maintained:

@actual %indexOf @keyFor 0 [ C_value ]* { A => 1 }* [ C ]* 1 [ A_value ] { B => 2 }* [ A ]* 2 [ B_value ] { C => 0 }* [ B ]* 3 [ D_value ] { D => 3 }* [ D ]* 4 [ E_value ] { E => 4 }* [ E ]*

but requires two splices and the for loop is expensive!


Using etcshadow's layout, if I use splice to reorder @keys, the linkages in the hashes are self maintaining; but:

@keys %valByKey %keyByValRef 0 [ A ] { A => \A_value } { \A_value => A } 1 [ B ] { B => \B_value } { \B_value => B } 2 [ C ] { C => \C_value } { \C_value => C } 3 [ D ] { D => \D_value } { \D_value => D } 4 [ E ] { E => \E_value } { \E_value => E }

If accessing C via key, calls for C to become top item getByKey( 'C' ); does?

sub getByKey { my $key = shift; my $value = $valByKey{ $key }; ## In order to splice the C item to the top ## I need it's index, but I don't have a way ## to go from key 'C' to index? return $value; }

If there was a version of splice that located the items to remove by its address rather than by index, I would be laughing.


Using a hybrid of the two:

@keys %valByKey %idxByVal 0 [ A ] { A => \A_value } { \A_value => 0 } 1 [ B ] { B => \B_value } { \B_value => 1 } 2 [ C ] { C => \C_value } { \C_value => 2 } 3 [ D ] { D => \D_value } { \D_value => 3 } 4 [ E ] { E => \E_value } { \E_value => 4 }

Accessing C via key calls for C to become top item getByKey( 'C' ); does:

sub getByKey { my $key = shift; my $value = $valByKey{ $key }; my $idx = $idxByVal{ $value }; push @keys, splice @keys, $idx, 1; ## To maintain linkage, it becomes necessary ## to completely re-build %idxByVal %idxByValue = map{ $valByKey{ $key[ $_ ] } => $_ } 0 .. $#keys; return $value; }

Afterwards:

@keys %valByKey %idxByVal 0 [ C ] { A => \A_value } { \A_value => 0 } 1 [ A ] { B => \B_value } { \B_value => 1 } 2 [ B ] { C => \C_value } { \C_value => 2 } 3 [ D ] { D => \D_value } { \D_value => 3 } 4 [ E ] { E => \E_value } { \E_value => 4 }

One splice and a somewhat more expensive (because of double indirection) loop!

I'm still looking at the other two suggestions.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

In reply to Re^4: Re-orderable keyed access structure? by BrowserUk
in thread Re-orderable keyed access structure? by BrowserUk

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.