in reply to Delete all hash keys except for n of them

Here is one way:

use strict; use warnings; my %hash; @hash{ 'a' .. 'z' } = ( 1 .. 26 ); print 'Total elements in %hash before deletion: ', scalar keys %hash, "\n"; delete $hash{ +each %hash } for 1 .. keys( %hash ) - 5; print 'Total elements in %hash after deletion: ', scalar keys %hash, "\n";

The only important line is the one starting with delete. You might wonder about the wisdom in deleting hash elements while using each, but if you check the documentation for each, you'll find it states: "It is always safe to delete the item most recently returned by each(), ..."

This method works by first calling keys in scalar context to get the number of keys, and then subracting five. That is used as the high end of the range of 1 .. n - 5. for iterates over that range, and on each iteration, each is called in scalar context, where it returns the next key. That expression is evaluated inside the  { ... } brackets of $hash{ ... }, so you're basically specifying a hash element. And that hash element is presented to delete for removal. The process repeats itself until only five elements remain.

I have to admit, the concept of blindly deleting all but five hash elements seems a little wierd. You're not deleting a truely random sequence, and you're not deleting an ordered sequence. Unless you don't care that what remains is neither random nor predictable, I have no idea how it's useful to do this. ;)


Dave