Delete all hash entries except for a specific list

2004-09-21 Thread Bob Showalter
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 = @[EMAIL PROTECTED];
%hash = ();
@[EMAIL PROTECTED] = @values;

Is there a more elegant approach?

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Delete all hash entries except for a specific list

2004-09-21 Thread Gunnar Hjalmarsson
Bob Showalter wrote:
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 = @[EMAIL PROTECTED];
%hash = ();
@[EMAIL PROTECTED] = @values;
Is there a more elegant approach?
This is slightly shorter:
%hash = map { $_, $hash{$_} } qw(bar qux);
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response



Re: Delete all hash entries except for a specific list

2004-09-21 Thread Jeff 'japhy' Pinyan
On Sep 21, Bob Showalter said:

   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).

my @keys = qw(bar qux);

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



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Delete all hash entries except for a specific list

2004-09-21 Thread Errin Larsen
On Tue, 21 Sep 2004 14:58:43 -0400 (EDT), Jeff 'japhy' Pinyan
[EMAIL PROTECTED] wrote:
 On Sep 21, Bob Showalter said:
 
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).
 
 my @keys = qw(bar qux);
 
 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
 
 


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

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Delete all hash entries except for a specific list

2004-09-21 Thread Jeff 'japhy' Pinyan
On Sep 21, Errin Larsen said:

On Tue, 21 Sep 2004 14:58:43 -0400 (EDT), Jeff 'japhy' Pinyan
[EMAIL PROTECTED] wrote:
 On Sep 21, Bob Showalter said:

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).

 my @keys = qw(bar qux);

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

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

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 )

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;
@[EMAIL PROTECTED] = ();  # 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


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Delete all hash entries except for a specific list

2004-09-21 Thread John W. Krahn
Bob Showalter wrote:
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 = @[EMAIL PROTECTED];
%hash = ();
@[EMAIL PROTECTED] = @values;
Is there a more elegant approach?
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
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response