Re: Parsing a hash table for only variables that are uppercase.
by rob_au (Abbot) on Mar 24, 2002 at 00:18 UTC
|
As always there are many ways to do this - the first which came to my mind was to use grep. eg.
foreach my $key ( grep { /^[A-Z]+$/ } keys %runset ) {
print $key, " ", $runset{$key}, "\n";
}
... But if you really wanted to delete the non-uppercase hash elements, then expanding on this usage of grep ...
delete $runset{$_} for ( grep { !/^[A-Z]+$/ } keys %runset );
perl -e 's&&rob@cowsnet.com.au&&&split/[@.]/&&s&.com.&_&&&print' | [reply] [d/l] [select] |
|
Minor regex nit:
Rather than checking the entire key for having uppercase letters and then negating the rest, you could check for the presence of any non-uppercase letter:
delete $runset{$_} for ( grep { /[^A-Z]/ } keys %runset );
Of course, this will also allow the null hash key as well, so you might want to extend the grep to grep { $_ && /[^A-Z]/ }, and by that point, you may have sacrificed the savings on the regex.
- Richie
| [reply] [d/l] [select] |
Re: Parsing a hash table for only variables that are uppercase.
by Albannach (Monsignor) on Mar 24, 2002 at 00:28 UTC
|
Well since you say delete you could use something like
for (keys %runset) {
unless($_ eq uc($_)) {
delete $runset{$_};
}
}
before your printing loop.
However you have another problem:
a hash is un-ordered, so you won't get the sentence you expect
unless you are very lucky - you need some way to specify the order in
which the values of the uppercase keys are printed. The example
you provide doesn't work for a simple sort of the uppercase keys
so you'll have to think of something else.
--
I'd like to be able to assign to an luser | [reply] [d/l] |
|
#!/usr/bin/perl -w
use strict;
use Tie::IxHash;
tie my %ordered_hash, Tie::IxHash;
%ordered_hash = (a => 1, b => 2, c => 3);
foreach my $key ( keys %ordered_hash ) {
print "$key\t$ordered_hash{$key}\n";
}
# prints:
# a 1
# b 2
# c 3
exit 0;
Cheers,
Richard
| [reply] |
Re: Parsing a hash table for only variables that are uppercase.
by seattlejohn (Deacon) on Mar 24, 2002 at 00:33 UTC
|
A previous reply gives some methods for deleting keys are that aren't upper case, but there's one other thing that you should be aware of: hash keys are not stored (or returned by keys) in any particular order. So your code might print "I am a monk in training", or it might print "a monk in training am I", which sounds like something Yoda might utter.
Actually, as long as your print statement includes $key, your output is also not going to be formatted quite as you expect: "TEST IABC amBAR a monk in training" is one possibility. (Note the lack of spaces, too.) What you really want inside the loop is probably something like this: print $runset{$key}, " " Or, even more Perlish, get rid of the enclosing loop and just use this: print join " ", values %runset; This latter version also eliminates the trailing space, because join only inserts delimiters between list elements. | [reply] [d/l] [select] |
Re: Parsing a hash table for only variables that are uppercase.
by Rhodium (Scribe) on Mar 24, 2002 at 01:15 UTC
|
Thanks for the replies. I really do appreciate it!
Now I want to expand this a pinch, now that some of you think my deleting of hash keys is not needed.
I have two hash tables (%runset and %description) and I want to do the following. All of the keys in %runset have precendence over %description. BUT if there are "new" ones in %description, I don't want to forget those either.. So here was my thoughts on how to do this..
1. Only valid runset variables in %runset are Uppercase(This is why deleting them is easier..)
2. Comparing the two hashes grab %runset first and as you print them delete them from both hashes (if they exist in %description - which they might not).
3. Now any remaining hashes in %description print them as well.
Am I crazy?
If you want to try your hand at this code I would really be indebted to you all. Thanks much!!
| [reply] |
|
This is actually much easier than you might expect - Essentially you are looking at merging two hashes with the key-values of %runset having precedence of those in %description. This can be done as follows:
delete $runset{$_} for ( grep { !/^[A-Z]+$/ } keys %runset );
%merged_hash = ( %description, %runset );
This code will delete the non-uppercase key-value pairs in the %runset and then merge the two hashes - Any values in %description with an identical key-name in %runset will be replaced with the values in the latter (based on left-to-right execution).
perl -e 's&&rob@cowsnet.com.au&&&split/[@.]/&&s&.com.&_&&&print'
| [reply] [d/l] [select] |
|
$
$ perl -e 's&&rob@cowsnet.com.au&&&split/[@.]/&&s&.com.&_&&&print'
In string, @cowsnet now must be written as \@cowsnet at -e line 1, nea
+r "rob@cowsnet"
Execution of -e aborted due to compilation errors.
$ perl -e 's&&rob\@cowsnet.com.au&&&split/[@.]/&&s&.com.&_&&&print'
rob@cowsnet_au$
Am I missing something?
HTH,
Danny
Update:
$ perl -v
This is perl, v5.6.0 built for i586-linux
Copyright 1987-2000, Larry Wall
.
.
.
| [reply] [d/l] [select] |
|
Re: Parsing a hash table for only variables that are uppercase.
by pizza_milkshake (Monk) on Mar 24, 2002 at 19:43 UTC
|
Not sure if this is the *best* way, but I'm lazy and it works for me
#!/usr/bin/perl
use strict;
my %h = qw/A a B b c c/;
my %h2;
$h2{$_} = $h{$_} for grep {/^[^a-z]$/} keys %h;
perl -MLWP::Simple -e'$_="104116116112058047047112097114115101101114114111114046099111109047112"; $s .= chr for/(...)/g;getprint $s' |more
| [reply] [d/l] |