Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have a hash containing 10 key-value pairs and would like to remove the first 3 of these off the hash. How would I do this? Thanks UK

Replies are listed 'Best First'.
Re: Hash manipulation
by thelenm (Vicar) on Nov 14, 2002 at 21:37 UTC
    Hashes don't have a clear ordering, so I'm not sure what you want to do. If you are saying you want to remove the hash entries for the first three keys as sorted in alphabetical order(?), you might do it like this.
    delete $hash{$_} for (sort keys %hash)[0..2];

    -- Mike

    --
    just,my${.02}

Re: Hash manipulation
by nothingmuch (Priest) on Nov 14, 2002 at 21:53 UTC
    Assuming you mean in the order they were saved in the hash, the module Tie::IxHash provides such access. It should have sufficient examples, but i'll briefly describe what it does...

    When you tell perl to bind a normal hash interface with what's called a tied object, in this case a Tie::IxHash tied object, the object takes care of the internals. The Tie::IxHash module provides internal structures which contain regular hashes and arrays, containing additional data to determine the order, not only the value. The interface is the same, but allowes different functionality.

    When you've tied your hash to a Tie::IxHash you may then delete(@hash{(keys)[0 .. 2]}). That approach, though functional, is good for 10 elements but not many more. You should probably delete iteratively, using each.

    Update: Changed IxHash to Tie::IxHash, squashed a typo.

    -nuffin
    zz zZ Z Z #!perl
Re: Hash manipulation
by Anonymous Monk on Nov 14, 2002 at 23:42 UTC
    Ooh, it depends on what you mean by 'the first 3'. Key-value pairs in Perl aren't stored in any workable order - you're not *guarenteed* to get them out in the order you put them in. So if your question is, "How do I remove the first three I put in?", the answer is, "Don't put them in to begin with!" Seriously, to give you at least one useful answer, perhaps you don't care about the order, and the first three you get will be fine? Try something like:
    %test = ( a => 1, b => 2, c => 3, d => 4, e => 5, f => 6, g => 7, h => 8, i => 9, j => 10, ); delete $test{each( %test )}; delete $test{each( %test )}; delete $test{each( %test )}; print map "$_ : $test{$_}\n", keys %test;
    ...but don't rely on the order of 'each' - it could turn around and bite ya! Kris, (Also UK...)
Re: Hash manipulation
by Chief of Chaos (Friar) on Nov 15, 2002 at 07:28 UTC
    Hi, use Tie::IxHash to make this hash.

    Example :
    #!/usr/local/bin/perl -w use strict; # init use Tie::IxHash; tie %keyvals, "Tie::IxHash"; # insert the keys $keyvals{"First"} = "12345"; $keyvals{"Second"}= "23456"; $keyvals{"Third"} = "34567"; $keyvals{"Fourth"}= "45678"; $keyvals{"Fifth"} = "56789"; # delete first three keyvals delete @keyvals{ (sort keys %keyvals)[0..2] }; # print it out print map "$_ : $keyvals{$_}\n", keys %keyvals;
    good luck with this
Re: Hash manipulation
by pg (Canon) on Nov 14, 2002 at 21:45 UTC
    if you want a partically order, try to use sort function, you can get info from perlfunc.