Re: hash lookup with regex

2003-08-23 Thread Shevek
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

2003-08-20 Thread Peter Haworth
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

2003-08-20 Thread Martin Bower
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

2003-08-19 Thread Andy Ford
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

2003-08-19 Thread Mark Fowler
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

2003-08-19 Thread Martin Bower
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

2003-08-19 Thread Steve Keay
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

2003-08-19 Thread Dave Cross

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

2003-08-19 Thread James E Keenan
 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

2003-08-19 Thread James E Keenan

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