[Golf-ish] Ordered hash keys

Discussion in 'Perl Misc' started by Damian James, Apr 29, 2005.

  1. Damian James

    Damian James Guest

    Hi folks,

    So I wanted to define a lookup table that I would later need to
    iterate over in a specific order. That's easy enough, there are
    many ways to do it; but I specifically wanted to keep the neat,
    visually oriented table in my code:

    my @mappings = (
    field1 => 'otherLongwindedDirectoryAttribute',
    field2 => 'kitchenSink',
    field3 => 'userDistanceBetweenEyes'
    );
    my %lookup = @mappings;
    my @fields = @mappings[ map $_*2, 0..($#mappings/2) ];

    ....where obviously I am only interested in %lookup and @fields, but
    want to keep the table in the interests of easy alteration.

    So how might I avoid defining @mappings? Is there a simpler, shorter
    or more elegant 'hashificator' that might be suitable in place of the
    arithmetic one I've shown? People maintaining this later may well not
    be able to find their own um, keyboard, with detailed directions and
    a map, but just might be able to change a lookup table if it's clear
    enough and the instructions are sufficiently detailed.

    I know I can:

    my %lookup;
    @lookup{ my @fields = qw/field1 field2 field3/ } =
    qw/other kitch user/;

    But that sacrifices the vertical orientation, and that just won't fit
    neatly with the rather long directory attribute names.

    This is obviously a style question more than anything, so the more
    playful the suggestions the better I guess ;).

    --damian
    --
    @:=grep!(m!$/|#!..$|),split//,<DATA>;@;=0..$#:;while($:=@;){$;=rand
    $:--,@;[$;,$:]=@;[$:,$;]while$:;push@|,shift@;if$;[0]==@|;select$,,
    $,,$,,1/80;print qq x\bxx((@;+@|)*$|++),@:[@|,@;],!@;&&$/} __END__
    Just another Perl Hacker,
     
    Damian James, Apr 29, 2005
    #1
    1. Advertising

  2. * Damian James schrieb:
    >
    > So I wanted to define a lookup table that I would later need to
    > iterate over in a specific order. That's easy enough, there are
    > many ways to do it; but I specifically wanted to keep the neat,
    > visually oriented table in my code:
    >
    > my @mappings = (
    > field1 => 'otherLongwindedDirectoryAttribute',
    > field2 => 'kitchenSink',
    > field3 => 'userDistanceBetweenEyes'
    > );
    > my %lookup = @mappings;
    > my @fields = @mappings[ map $_*2, 0..($#mappings/2) ];
    >
    > ...where obviously I am only interested in %lookup and @fields, but
    > want to keep the table in the interests of easy alteration.


    When typing `perldoc -q "keep my hash sorted"` I get:

    Found in C:\Programme\Perl\lib\pod\perlfaq4.pod
    How can I always keep my hash sorted?
    You can look into using the DB_File module and tie() using the $DB_BTREE
    hash bindings as documented in "In Memory Databases" in DB_File. The
    Tie::IxHash module from CPAN might also be instructive.

    Have a look at this Tie::IxHash from CPAN. Your code could look like:


    use Tie::IxHash;
    tie( my %lookup, 'Tie::IxHash',
    field1 => 'otherLongwindedDirectoryAttribute',
    field2 => 'kitchenSink',
    field3 => 'userDistanceBetweenEyes'
    );
    my @fields = keys %lookup;


    But I think you don't need your array @fields anymore when using this
    module. When keep sorted your Hash by another value have a look at
    Tie::Hash::Sorted. In the past many people have thought about ordered
    hashes -- I think you won't reinventing the wheel ... ;-)

    regards,
    fabian
     
    Fabian Pilkowski, Apr 30, 2005
    #2
    1. Advertising

  3. Damian James <> wrote:

    > my @fields = @mappings[ map $_*2, 0..($#mappings/2) ];


    > Is there a simpler, shorter
    > or more elegant 'hashificator' that might be suitable in place of the
    > arithmetic one I've shown?



    You can save 3 strokes by generating the slice indexes with:

    grep $_%2, 0..$#mappings

    instead of map().


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Apr 30, 2005
    #3
  4. Damian James

    Peter Wyzl Guest

    "Damian James" <> wrote in message
    news:...
    : Hi folks,
    :
    : So I wanted to define a lookup table that I would later need to
    : iterate over in a specific order. That's easy enough, there are
    : many ways to do it; but I specifically wanted to keep the neat,
    : visually oriented table in my code:
    :
    : my @mappings = (
    : field1 => 'otherLongwindedDirectoryAttribute',
    : field2 => 'kitchenSink',
    : field3 => 'userDistanceBetweenEyes'
    : );
    : my %lookup = @mappings;
    : my @fields = @mappings[ map $_*2, 0..($#mappings/2) ];
    :
    : ...where obviously I am only interested in %lookup and @fields, but
    : want to keep the table in the interests of easy alteration.


    I have previously done somthing like:

    my %lookup = (
    field1 => 'otherLongwindedDirectoryAttribute',
    field2 => 'kitchenSink',
    field3 => 'userDistanceBetweenEyes'
    );

    my @fields = sort(keys(%lookup));

    But this relies on sort giving you the order you want rather than a specific
    order which may not necessarily match sort's output. Unless you can define
    some sort routine that matches your preferred order. In the example given
    it would match but that is probably just a happy coincidence of your example
    data. How critical is the 'preferred order' of the keys compared to a
    'sorted order' of the keys for later processing?

    P
     
    Peter Wyzl, Apr 30, 2005
    #4
  5. Damian James

    Anno Siegel Guest

    Tad McClellan <> wrote in comp.lang.perl.misc:
    > Damian James <> wrote:
    >
    > > my @fields = @mappings[ map $_*2, 0..($#mappings/2) ];

    >
    > > Is there a simpler, shorter
    > > or more elegant 'hashificator' that might be suitable in place of the
    > > arithmetic one I've shown?

    >
    >
    > You can save 3 strokes by generating the slice indexes with:
    >
    > grep $_%2, 0..$#mappings
    >
    > instead of map().


    Yes, but that selects odd elements, not even ones.

    Anno
     
    Anno Siegel, May 2, 2005
    #5
  6. Damian James

    Bart Lateur Guest

    Fabian Pilkowski wrote:

    >When typing `perldoc -q "keep my hash sorted"` I get:
    >
    > Found in C:\Programme\Perl\lib\pod\perlfaq4.pod
    > How can I always keep my hash sorted?
    > You can look into using the DB_File module and tie() using the $DB_BTREE
    > hash bindings as documented in "In Memory Databases" in DB_File. The
    > Tie::IxHash module from CPAN might also be instructive.
    >
    >Have a look at this Tie::IxHash from CPAN.


    See also Tie::Hash::Indexed, which is an XS implementation.

    <http://search.cpan.org/search?module=Tie::Hash::Indexed>


    I wish module authors chose their names so it's more obvious what other
    modules they're related to.

    --
    Bart.
     
    Bart Lateur, May 3, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. rp
    Replies:
    1
    Views:
    581
    red floyd
    Nov 10, 2011
  2. Xeno Campanoli
    Replies:
    16
    Views:
    286
    Martin DeMello
    Aug 25, 2005
  3. Alex Fenton

    Hash#values and Hash#keys order

    Alex Fenton, Apr 7, 2006, in forum: Ruby
    Replies:
    1
    Views:
    161
    George Ogata
    Apr 15, 2006
  4. Trans

    [GOLF] *args to Hash

    Trans, Oct 10, 2006, in forum: Ruby
    Replies:
    1
    Views:
    91
    Trans
    Oct 10, 2006
  5. DL

    Ordered list inside ordered list

    DL, Nov 9, 2009, in forum: Javascript
    Replies:
    6
    Views:
    355
    Dr J R Stockton
    Nov 21, 2009
Loading...

Share This Page