Forum Moderators: coopster & phranque

Message Too Old, No Replies

Perl Hash keys: Delete all keys similar to "xyz-"?

Wildcard delete?

         

Brett_Tabke

8:05 pm on Jan 12, 2002 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Is there an easy way to delete a series of like hash keys?

$foo{'bar-xyz'}=1;
$foo{'bar-abc'}=1;

I'd like to delete all keys that start "bar-". Anyway to do that quickly?

amoore

8:39 pm on Jan 12, 2002 (gmt 0)

10+ Year Member



here's a pretty readable way:

foreach ( keys( %foo ) ) {
delete $foo{$_} if ( /^bar-/ );
}

Brett_Tabke

9:02 pm on Jan 12, 2002 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



That's close to what I'm using now, but on 20k keys, that takes some time to delete just a few.

amoore

3:46 pm on Jan 14, 2002 (gmt 0)

10+ Year Member



well, if you can generate an array with all of the keys that you want to delete in it (perhaps as you're building the hash or something) then deleting them could be done with a slice like this:
delete @fooHash{@abcKeysArray}
That would also help if you had to delete all those keys multiple times, from different hashes or something. Notice that not all of the elements in @abcKeysArray need be found in %fooHash. I guess that means that you could make @abcKeysArray contain all of the possible keys you need deleted.

There's probably a more clever way to delete stuff out of there with a slice that does it really well. I find that these queestions or often answered very well by the guys at perlmonks.org

If you've got 20k keys in your hash, I bet you're pulling it from a database. Perhaps pulling it out with more specific SQL like "minus the ones like 'abc-%'" or "where key not like 'abc-%'" or something woud be more efficient.

sugarkane

4:59 pm on Jan 15, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Using a while loop may be faster than foreach:

while (($k,$v) = each(%foo)) {
delete $foo{$k} if ( $k=~/^bar-/ );
}

> If you can generate an array with all of the keys

Something like

@array=grep /^bar-/, keys %foo;

would probably work, but again I've not tested the speed. They're both variations on a theme though, and I can't see any major speed improvements being likely.