Re: hash lookup with regex
On Tue, 19 Aug 2003, Martin Bower wrote: I have 2 hashes, one with 10,000 entries and the other with 5,000, and these are loaded from a database table(sybase). %hash1 contains values such as 111.666.fff.jjj.ccc.222 %hash2 contains values such as 111.666.fff.___.ccc.222 (where the ___ can eixst in any position) This is a job for a tree. S. -- Shevekhttp://www.anarres.org/ I am the Borg. http://www.gothnicity.org/
Re: hash lookup with regex
On Tue, 19 Aug 2003 06:07:24 -0700, Dave Cross wrote: From: Martin Bower [EMAIL PROTECTED] Date: 8/19/03 11:31:16 AM %hash1 contains values such as 111.666.fff.jjj.ccc.222 %hash2 contains values such as 111.666.fff.___.ccc.222 (where the ___ can eixst in any position) is there a quick way for me to see if a value contained in %hash2 exists in %hash1 ? without resorting to as nested loop foreach hash? Can't you get the keys of both hashes into arrays then find the intersection using the algorithms in the FAQ? Can't you use Dave's Tie::Hash::Regex? tie %hash1 'Tie::Hash::Regex'; # ... populate %hash1 and %hash2 foreach(keys %hash2){ (my $check=quotemeta $check)=~s/_/./g; if($hash1{qr/$check/}){ print Some key matches $check\n; } } Well, you can't tell which key matches, so how about using Tie::RegexpHash? # ... populate %hash1 tie %hash2 'Tie::RegexpHash'; while(my($k,$v)=$sth-fetchrow_array){ (my $check=quotemeta $k)=~s/_/./g; $hash2{qr/$check/}=$v; } foreach my $key(keys %hash1){ if(exists $hash2{$key}){ print $key matches some check\n; } } H, you can't tell which check the key matches with this method. In any event, both of these approaches do iterate through the hash behind the scenes, so you can't get away from that, only hide it under the carpet. -- Peter Haworth [EMAIL PROTECTED] %SYSTEM-F-ANARCHISM, the operating system has been overthrown
Re: hash lookup with regex
thanks for suggestions, I liked Tie::Hash::Regex ... could prove useful in the future. Martin _ Fotos - MSN Fotos das virtuelle Fotoalbum. Allen Freunden zeigen oder einfach online entwickeln lassen: http://photos.msn.de/support/worldwide.aspx
Re: hash lookup with regex
You could cast them both to arrays and use the perl module Algorithm::Diff to calculate the differences between them. This will check if the entry is in array1 and not in array2 and vice-versa - wonderful Andy On Tue, 2003-08-19 at 12:31, Martin Bower wrote: apologies for perl content :-) I have 2 hashes, one with 10,000 entries and the other with 5,000, and these are loaded from a database table(sybase). %hash1 contains values such as 111.666.fff.jjj.ccc.222 %hash2 contains values such as 111.666.fff.___.ccc.222 (where the ___ can eixst in any position) is there a quick way for me to see if a value contained in %hash2 exists in %hash1 ? without resorting to as nested loop foreach hash, as below ? foreach my $key ( keys %hash1 ) { foreach my $check ( keys %hash2 ) { $check =~ s/_/\./g; if ($key =~ $check) { print $key matches $check\n; } } } _ On the move? Get Hotmail on your mobile phone http://www.msn.co.uk/msnmobile
Re: hash lookup with regex
On Tue, 19 Aug 2003, Martin Bower wrote: is there a quick way for me to see if a value contained in %hash2 [after being mutated someway] exists in %hash1 ? without resorting to as nested loop foreach hash. If you've got the memory (and looking at it, you're not dealing with too many items yet, so you should have) it'd make more sense to precompute each possible key from the keys in %hash1 once and store that in a seperate hash, then all you'll need to do is look up the key from hash2 in that hash. Keep making the hashes bigger and bigger till you run out of physical memory[1]. Hashses are fast. Mark. [1] Though if you run out of physical memory then everything suddenly gets very very very very slow. -- #!/usr/bin/perl -T use strict; use warnings; print q{Mark Fowler, [EMAIL PROTECTED], http://twoshortplanks.com/};
Re: hash lookup with regex
Andy Ford wrote: You could cast them both to arrays and use the perl module Algorithm::Diff to calculate the differences between them. hmm. had a quick look and I don't think the MATCH function will match the regex either, the code below (taken from http://www.stonehenge.com/merlyn/UnixReview/col35.html ) doesnt produce any matches at all. maybe I'm missing something ( go easy on the responses to that one ) Martin my @mapping1 = (111.222.333.444,222.333.444.555,555.666.444.333,333.444.666.777); my @mapping2 = (111.222.444,222.333.444); traverse_sequences([EMAIL PROTECTED], [EMAIL PROTECTED], { MATCH = sub { show(MATCH,$mapping1[$_[0]], $mapping2[$_[1]]) }, DISCARD_A = sub { show(NO,$mapping1[$_[0]], ---) }, DISCARD_B = sub { show(NO, ---, $mapping2[$_[1]]) }, }); sub show { printf %5s %10s %10s\n, @_; } _ MSN - More Useful Every Day http://www.msn.de
Re: hash lookup with regex
On Tue, Aug 19, 2003 at 11:31:16AM +, Martin Bower wrote: %hash1 contains values such as 111.666.fff.jjj.ccc.222 %hash2 contains values such as 111.666.fff.___.ccc.222 (where the ___ can eixst in any position) If there is only ever one ___ in a value you could generate all 6 possibilities from hash1 and look them up directly in hash2. if ($hash2{'___.666.fff.jjj.ccc.222'} or $hash2{'111.___.fff.jjj.ccc.222'} or $hash2{'111.666.___.jjj.ccc.222'} or $hash2{'111.666.fff.___.ccc.222'} or $hash2{'111.666.fff.jjj.___.222'} or $hash2{'111.666.fff.jjj.ccc.___'} ){ warn found it! }
Re: hash lookup with regex
From: Martin Bower [EMAIL PROTECTED] Date: 8/19/03 11:31:16 AM apologies for perl content :-) I have 2 hashes, one with 10,000 entries and the other with 5,000, and these are loaded from a database table(sybase). %hash1 contains values such as 111.666.fff.jjj.ccc.222 %hash2 contains values such as 111.666.fff.___.ccc.222 (where the ___ can eixst in any position) is there a quick way for me to see if a value contained in %hash2 exists in %hash1 ? without resorting to as nested loop foreach hash, as below ? foreach my $key ( keys %hash1 ) { foreach my $check ( keys %hash2 ) { $check =~ s/_/\./g; if ($key =~ $check) { print $key matches $check\n; } } } Can't you get the keys of both hashes into arrays then find the intersection using the algorithms in the FAQ? Dave... -- http://www.dave.org.uk Let me see you make decisions, without your television - Depeche Mode (Stripped)
Re: hash lookup with regex
Message: 9 From: Martin Bower [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: hash lookup with regex Date: Tue, 19 Aug 2003 11:31:16 + I have 2 hashes, one with 10,000 entries and the other with 5,000, and %hash1 contains values such as 111.666.fff.jjj.ccc.222 %hash2 contains values such as 111.666.fff.___.ccc.222 (where the ___ can eixst in any position) Given your code below, I assume you mean: %hash1 contains *keys* such as 111.666.fff.jjj.ccc.222. If so, then the *values* of %hash1 and %hash2 are either irrelevant or need only be a true value. If so, ... is there a quick way for me to see if a value contained in %hash2 exists in %hash1 ? without resorting to as nested loop foreach hash, as below ? ... then in addition to Algorithm::Diff (as suggested by Andy Ford [EMAIL PROTECTED]), you might also consider List::Compare::SeenHash: use List::Compare::SeenHash; my %hash1 = ( '111.666.fff.jjj.ccc.222' = 1, '111.666.fff.jjj.ccc.333' = 22, '111.666.fff.jjj.ccc.444' = 72, '111.666.fff.jjj.ccc.666' = 57, ); my %hash2 = ( '111.666.___.fff.jjj.ccc.222' = 1, '111.666.fff.jjj.ccc.___.333' = 73, '111.666.___.fff.jjj.ccc.333' = 57, '111.666.fff.jjj.ccc.555' = 602, '111.666.___.fff.___.jjj.ccc.666' = 79, ); my (%hash2plus, @intersection); foreach my $check (keys %hash2) { $check =~ s|_+\.||g; $hash2plus{$check}++; } my $lcsh = List::Compare::SeenHash-new(\%hash1, \%hash2plus); @intersection = $lcsh-get_intersection; print After stripping underscores, found in both: $_\n foreach @intersection; As the author of this CPAN module, I would appreciate feedback on its usefulness with hashes of your size. Jim Keenan
Re: hash lookup with regex
Eeek! I cut-and-pasted the wrong text as part of my last post. I should have stated: Given your code below, I assume you mean: %hash1 contains *keys* such as 111.666.fff.jjj.ccc.222. If the *values* of %hash1 and %hash2 are strictly numeric (as would be the case if these are seen-hashes), then ... [snip] ... then in addition to Algorithm::Diff ..., you might also consider List::Compare::SeenHash: [snip code example] Jim Keenan