Professional Web Applications Themes

Delete all hash entries except for a specific list - PERL Beginners

Consider, my %hash = ( foo => 1, bar => 2, baz => 3, qux => 4, ); I would like to remove all the entries in the hash except for 'bar' and 'qux'. (Actual hash has other entries which can vary at runtime. I know that I only want to keep 'bar' and 'qux' however). Here's what I'm doing: my keys = qw(bar qux); my values = hash{keys}; %hash = (); hash{keys} = values; Is there a more elegant approach?...

  1. #1

    Default Delete all hash entries except for a specific list

    Consider,

    my %hash = (
    foo => 1,
    bar => 2,
    baz => 3,
    qux => 4,
    );

    I would like to remove all the entries in the hash except for 'bar' and
    'qux'. (Actual hash has other entries which can vary at runtime. I know that
    I only want to keep 'bar' and 'qux' however).

    Here's what I'm doing:

    my keys = qw(bar qux);
    my values = hash{keys};
    %hash = ();
    hash{keys} = values;

    Is there a more elegant approach?
    Bob Guest

  2. #2

    Default Re: Delete all hash entries except for a specific list

    Bob Showalter wrote: 

    This is slightly shorter:

    %hash = map { $_, $hash{$_} } qw(bar qux);

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Guest

  3. #3

    Default Re: Delete all hash entries except for a specific list

    On Sep 21, Bob Showalter said:
     
     

    You could do:

    my %keep_these_keys;
    keep_these_keys{qw( bar qux )} = ();

    delete hash{ grep !exists $keep_these_keys{$_}, keys %hash };

    --
    Jeff "japhy" Pinyan % How can we ever be the sold short or
    RPI Acacia Brother #734 % the cheated, we who for every service
    http://japhy.perlmonk.org/ % have long ago been overpaid?
    http://www.perlmonks.org/ % -- Meister Eckhart


    Jeff Guest

  4. #4

    Default Re: Delete all hash entries except for a specific list

    On Tue, 21 Sep 2004 14:58:43 -0400 (EDT), Jeff 'japhy' Pinyan
    <org> wrote: 

    >
    > You could do:
    >
    > my %keep_these_keys;
    > keep_these_keys{qw( bar qux )} = ();
    >
    > delete hash{ grep !exists $keep_these_keys{$_}, keys %hash };
    >
    > --
    > Jeff "japhy" Pinyan % How can we ever be the sold short or
    > RPI Acacia Brother #734 % the cheated, we who for every service
    > http://japhy.perlmonk.org/ % have long ago been overpaid?
    > http://www.perlmonks.org/ % -- Meister Eckhart
    >
    >[/ref]


    So ... is there a way to return a 'not' slice of hashes? What I mean
    is, the 'keys' function returns a list of all keys in a slice. Is
    there a function to return a list of all keys in slice EXCEPT those
    keys that I explicitely pass? like this, maybe:

    my %my_hash = (
    foo => 1,
    bar => 2,
    baz => 3,
    qux => 4,
    );

    my other_keys = not_keys( %my_hash, "foo", "bar" )

    and then other_keys = qw( baz qux )

    ???

    --Errin
    Errin Guest

  5. #5

    Default Re: Delete all hash entries except for a specific list

    On Sep 21, Errin Ln said:
     
    >> 
    >>
    >> my %keep_these_keys;
    >> keep_these_keys{qw( bar qux )} = ();
    >>
    >> delete hash{ grep !exists $keep_these_keys{$_}, keys %hash };[/ref]
    >
    >So ... is there a way to return a 'not' slice of hashes? What I mean
    >is, the 'keys' function returns a list of all keys in a slice. Is
    >there a function to return a list of all keys in slice EXCEPT those
    >keys that I explicitely pass? like this, maybe:
    >
    >my %my_hash = (
    > foo => 1,
    > bar => 2,
    > baz => 3,
    > qux => 4,
    >);
    >
    >my other_keys = not_keys( %my_hash, "foo", "bar" )
    >
    >and then other_keys = qw( baz qux )[/ref]

    Write your own function. This is where prototypes come in handy:

    # declare the function BEFORE you use it
    # we could also define it here, but that might look ugly
    sub not_keys (\%);

    # ...

    my other_keys = not_keys(%my_hash, "foo", "bar");

    # ...

    sub not_keys (\%) {
    my $hash = shift;
    my %exclude;
    exclude{_} = (); # build hash of keys to exclude
    return grep !exists $exclude{$_}, keys %$hash;
    }

    --
    Jeff "japhy" Pinyan % How can we ever be the sold short or
    RPI Acacia Brother #734 % the cheated, we who for every service
    http://japhy.perlmonk.org/ % have long ago been overpaid?
    http://www.perlmonks.org/ % -- Meister Eckhart

    Jeff Guest

  6. #6

    Default Re: Delete all hash entries except for a specific list

    Bob Showalter wrote: 

    I don't know if it is more elegant but you could do it like this:

    %hash = map $_, grep $_->[0] =~ /^(?:bar|qux)$/, map [ $_, $hash{$_} ], keys
    %hash;

    :-)

    John
    --
    use Perl;
    program
    fulfillment
    John Guest

Similar Threads

  1. Hash Print and Delete
    By Jeff Westman in forum PERL Beginners
    Replies: 12
    Last Post: October 10th, 08:18 PM
  2. Q: detect non-existent hash entries w/function?
    By Daniel Friedman in forum PERL Miscellaneous
    Replies: 9
    Last Post: July 2nd, 06:00 PM
  3. Replies: 2
    Last Post: June 25th, 06:48 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139