keys %hash without destory element order

Discussion in 'Perl Misc' started by Fei Liu, Jan 11, 2007.

  1. Fei Liu

    Fei Liu Guest

    Hi Group, what should I do to keep the order of elements in a hash when
    I iterate through it? Example:

    Code:
    %hash = (a, b, c, d, e, f, ca, cb);
    foreach (keys %hash){ print "$_ => $hash{$_}\n"; }

    Result:
    e => f
    c => d
    a => b
    ca => cb

    How to make it output:
    a => b
    c => d
    e => f
    ca => cb

    Thanks,
     
    Fei Liu, Jan 11, 2007
    #1
    1. Advertising

  2. Fei Liu wrote:
    > Hi Group, what should I do to keep the order of elements in a hash when
    > I iterate through it? Example:
    >
    > Code:


    Don't forget to include:

    use warnings;
    use strict;

    > %hash = (a, b, c, d, e, f, ca, cb);


    Don't use barewords, quote your strings.

    my %hash = ( 'a', 'b', 'c', 'd', 'e', 'f', 'ca', 'cb' );

    Or:

    my %hash = qw( a b c d e f ca cb );

    > foreach (keys %hash){ print "$_ => $hash{$_}\n"; }
    >
    > Result:
    > e => f
    > c => d
    > a => b
    > ca => cb
    >
    > How to make it output:
    > a => b
    > c => d
    > e => f
    > ca => cb


    my %hash = qw( a b c d e f ca cb );
    my @order = qw( a c e ca );

    for my $key ( @order ) {
    print "$key => $hash{$key}\n";
    }




    John
    --
    Perl isn't a toolbox, but a small machine shop where you can special-order
    certain sorts of tools at low cost and in short order. -- Larry Wall
     
    John W. Krahn, Jan 11, 2007
    #2
    1. Advertising

  3. Fei Liu

    Paul Lalli Guest

    Fei Liu wrote:
    > Hi Group, what should I do to keep the order of elements in a hash when
    > I iterate through it? Example:


    You're confused. There *is no order* in a hash. There's no order to
    keep.

    If you'd like to use a structure that pretends to be a hash, but also
    has an order, download the Tie::IxHash module from CPAN

    Please see:
    http://search.cpan.org/~gsar/Tie-IxHash-1.21/lib/Tie/IxHash.pm
    perldoc -q cpan
    perldoc perlmodinstall

    Paul Lalli
     
    Paul Lalli, Jan 11, 2007
    #3
  4. Fei Liu wrote:
    > Hi Group, what should I do to keep the order of elements in a hash


    There is no such thing as the order of elements in a hash.

    jue
     
    Jürgen Exner, Jan 12, 2007
    #4
  5. Fei Liu

    Dr.Ruud Guest

    Fei Liu schreef:

    > Hi Group, what should I do to keep the order of elements in a hash
    > when I iterate through it? Example:
    >
    > Code:
    > %hash = (a, b, c, d, e, f, ca, cb);
    > foreach (keys %hash){ print "$_ => $hash{$_}\n"; }
    >
    > Result:
    > e => f
    > c => d
    > a => b
    > ca => cb
    >
    > How to make it output:
    > a => b
    > c => d
    > e => f
    > ca => cb


    If your order is an algorithm, like: "first by length, then
    alphabetical", then you can use sort.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
     
    Dr.Ruud, Jan 12, 2007
    #5
  6. Fei Liu

    gf Guest

    John W. Krahn wrote:

    > my %hash = qw( a b c d e f ca cb );
    > my @order = qw( a c e ca );
    >
    > for my $key ( @order ) {
    > print "$key => $hash{$key}\n";
    > }


    I tend to go at it a bit backwards to this...

    my @order = qw( a c e ca);
    my %hash;
    @hash{@order} = qw(b d f cb);

    Or just for a bit easier maintenance because the keys and values are
    easily aligned and checked visually...

    my @keys = qw( a c e ca );
    my @values = qw( b d f cb );
    my %hash;
    @hash{@keys} = @values;

    Then iterate through @keys however is desired and do the lookups in
    %hash as normal. It's not much different, but on hashes where you've
    absolutely got to retrieve keys in a certain order it works well.

    For big hashes it's unweildy to maintain though so I use an alternative
    of a dynamically built hash of hashes with the secondary hash
    containing a key that is the order to use and look at that value in an
    inline sort {}. It's a bit uglier for static lists of values but works
    nicely if you don't know how many elements there's going to be.

    Shootin' from the hip here...

    use strict;
    use warnings;

    my %hash;
    my $order = 0;

    # gather some arbitrary data...
    foreach ( 'A' .. 'Z' )
    {
    $hash{$_} = {
    'order' => $order++, # ...remember the order...
    'value' => ord($_) # ...remember the related value...
    };
    }

    # now walk through the keys, put them back in order...
    foreach ( sort { $hash{$a}->{'order'} <=> $hash{$b}->{'order'} } keys
    %hash )
    {
    print $_, ' => ', $hash{$_}->{'value'}, "\n"; # ...and print the
    values.
    }


    Or something like that.
     
    gf, Jan 12, 2007
    #6
  7. Fei Liu

    Bart Lateur Guest

    Paul Lalli wrote:

    >If you'd like to use a structure that pretends to be a hash, but also
    >has an order, download the Tie::IxHash module from CPAN


    Or its XS sibling, Tie::Hash::Indexed.

    --
    Bart.
     
    Bart Lateur, Jan 12, 2007
    #7
    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:
    563
    red floyd
    Nov 10, 2011
  2. 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
  3. Ronald Fischer

    Hash#keys, Hash#values order question

    Ronald Fischer, Aug 23, 2007, in forum: Ruby
    Replies:
    0
    Views:
    171
    Ronald Fischer
    Aug 23, 2007
  4. Iñaki Baz Castillo

    How to order a hash based on its keys?

    Iñaki Baz Castillo, Jun 21, 2011, in forum: Ruby
    Replies:
    11
    Views:
    682
    Iñaki Baz Castillo
    Jun 21, 2011
  5. Replies:
    1
    Views:
    140
    Prasad, Ramit
    Oct 19, 2012
Loading...

Share This Page