Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > In search of elegant code - searching keys of hashes in array

Reply
Thread Tools

In search of elegant code - searching keys of hashes in array

 
 
David Filmer
Guest
Posts: n/a
 
      12-11-2003
Suppose I have an array of hashes of names and social-security
numbers:

@ARRAY = (
{ first => 'John', last => 'Doe', ssn => '123-45-6789' },
{ first => 'Fred', last => 'Ree', ssn => '9876-54-321' }
);

Now suppose I want to print an error if any particular SSNs (say
'234-56-7890' and '0987-65-4321') are not found in my @ARRAY.
Obviously I can't just grep the array. I could build an intermediate
hash (%SSN) like this:

for (@ARRAY) { $SSN{$$_{'ssn'}}++ }
for (qw/234-56-7890 0987-65-4321/) {
print "Not found: $_\n" unless $SSN{$_}
}

but that's REALLY ugly (I don't like the creation of the intermediate
%SSN hash). I would appreciate suggestions for a more elegant
approach.
 
Reply With Quote
 
 
 
 
Eric J. Roode
Guest
Posts: n/a
 
      12-11-2003
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

http://www.velocityreviews.com/forums/(E-Mail Removed) (David Filmer) wrote in
news:(E-Mail Removed) om:

> Suppose I have an array of hashes of names and social-security
> numbers:
>
> @ARRAY = (
> { first => 'John', last => 'Doe', ssn => '123-45-6789' },
> { first => 'Fred', last => 'Ree', ssn => '9876-54-321' }
> );
>
> Now suppose I want to print an error if any particular SSNs (say
> '234-56-7890' and '0987-65-4321') are not found in my @ARRAY.
> Obviously I can't just grep the array. I could build an

intermediate
> hash (%SSN) like this:
>
> for (@ARRAY) { $SSN{$$_{'ssn'}}++ }
> for (qw/234-56-7890 0987-65-4321/) {
> print "Not found: $_\n" unless $SSN{$_}
> }
>
> but that's REALLY ugly (I don't like the creation of the

intermediate
> %SSN hash). I would appreciate suggestions for a more elegant
> approach.


I can't think of a better way. I think it's uglier to loop over the
@ARRAY each time you want to check a SSN.

Perhaps you can skip the (ugly?) creation of the intermediate hash by
representing your data differently? Or at least, maintaining the
%SSN hash alongside your @ARRAY data?

- --
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (MingW32) - WinPT 0.5.13

iD8DBQE/192QY96i4h5M0egRAot5AJ9RFzaafodA6bTCfdpkDZhb+GsP1g Cg+gXY
4nWr8yxFkPsHeTXaO9DGP44=
=ZrTm
-----END PGP SIGNATURE-----
 
Reply With Quote
 
 
 
 
Jim Keenan
Guest
Posts: n/a
 
      12-11-2003

"David Filmer" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Suppose I have an array of hashes of names and social-security
> numbers:
>
> @ARRAY = (
> { first => 'John', last => 'Doe', ssn => '123-45-6789' },
> { first => 'Fred', last => 'Ree', ssn => '9876-54-321' }
> );
>
> Now suppose I want to print an error if any particular SSNs (say
> '234-56-7890' and '0987-65-4321') are not found in my @ARRAY.
> Obviously I can't just grep the array. I could build an intermediate
> hash (%SSN) like this:
>
> for (@ARRAY) { $SSN{$$_{'ssn'}}++ }
> for (qw/234-56-7890 0987-65-4321/) {
> print "Not found: $_\n" unless $SSN{$_}
> }
>
> but that's REALLY ugly (I don't like the creation of the intermediate
> %SSN hash). I would appreciate suggestions for a more elegant
> approach.


Can you store your data in the form of a hash keyed by the SSN? After all,
setting aside fraud, the SSN uniquely identifies each individual and is made
to order as a hash key:

%SSN = (
123-45-6789 => ['John', 'Doe'],
9876-54-321 => ['Fred', 'Ree'],
);

Note that while the keys in your inner hash ('first', 'last', etc.) make it
easier to read, they don't add any semantic value and their repetition
increases the possibility of typing and coding errors.

jimk


 
Reply With Quote
 
Iain Chalmers
Guest
Posts: n/a
 
      12-11-2003
In article <VnRBb.48$(E-Mail Removed)>,
"Jim Keenan" <(E-Mail Removed)> wrote:

> Can you store your data in the form of a hash keyed by the SSN?


So long as you keep in mind what a US-centric solution that is...

Iain (I have no SSN, but I _may_ want to buy something from your website)

--
'When I first met Katho, she had a meat cleaver in one hand and
half a sheep in the other. "Come in", she says, "Hammo's not here.
I hope you like meat.' Sharkey in aus.moto
 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      12-11-2003
Iain Chalmers <(E-Mail Removed)> wrote in news:bigiain-
http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de:

> In article <VnRBb.48$(E-Mail Removed)>,
> "Jim Keenan" <(E-Mail Removed)> wrote:
>
>> Can you store your data in the form of a hash keyed by the SSN?

>
> So long as you keep in mind what a US-centric solution that is...
>
> Iain (I have no SSN, but I _may_ want to buy something from your website)


Well, I seriously doubt that this involves an ecommerce site. Entering your
SSN is hardly a prerequisite for making online purchases in the U.S.

Sinan.
--
A. Sinan Unur
(E-Mail Removed)
Remove dashes for address
Spam bait: (E-Mail Removed)
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      12-11-2003
>>>>> "DF" == David Filmer <(E-Mail Removed)> writes:

> Suppose I have an array of hashes of names and social-security
> numbers:


> @ARRAY = (
> { first => 'John', last => 'Doe', ssn => '123-45-6789' },
> { first => 'Fred', last => 'Ree', ssn => '9876-54-321' }
> );


> Now suppose I want to print an error if any particular SSNs (say
> '234-56-7890' and '0987-65-4321') are not found in my @ARRAY.
> Obviously I can't just grep the array. I could build an intermediate
> hash (%SSN) like this:


how is that obvious? you must have the classic newbie misconception that
grep only takes regexes which is wrong. grep can take any expression to
test. so you can grep your array easily:

foreach my $ssn ( qw( some ssn values) ) {

@found = grep $_->{ssn} eq $ssn, @array ;
do something based on @found
}


> for (@ARRAY) { $SSN{$$_{'ssn'}}++ }
> for (qw/234-56-7890 0987-65-4321/) {
> print "Not found: $_\n" unless $SSN{$_}
> }


> but that's REALLY ugly (I don't like the creation of the intermediate
> %SSN hash). I would appreciate suggestions for a more elegant
> approach.


as someone else said, indexing by ssn is another solution and one i
would recommend. if you do this search often, then building the other
hash is worth it and can be done even simpler than your example:

my %is_ssn ;
@is_ssn{ map $_->{ssn}, @ARRAY } = () ;
# test with exists

or

my %is_ssn = map { $_->{ssn}, 1} @ARRAY ;


but those only tell you if an ssn exists. if you want to find the record
by ssn just replace the 1 with $_ in the second and call the hash
ssn_to_rec or something similar.

uri

--
Uri Guttman ------ (E-Mail Removed) -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      12-11-2003
David Filmer <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> Suppose I have an array of hashes of names and social-security
> numbers:
>
> @ARRAY = (


Upper case names should be reserved for system variables (and a few
exceptions).

> { first => 'John', last => 'Doe', ssn => '123-45-6789' },
> { first => 'Fred', last => 'Ree', ssn => '9876-54-321' }
> );
>
> Now suppose I want to print an error if any particular SSNs (say
> '234-56-7890' and '0987-65-4321') are not found in my @ARRAY.
> Obviously I can't just grep the array.


Why not?

warn "boo: $ssn\n" unless grep $_->{ ssn} eq $ssn, @ARRAY;

It isn't particularly efficient, but perfectly valid.

> I could build an intermediate
> hash (%SSN) like this:


The only reason to do that would be efficiency.

> for (@ARRAY) { $SSN{$$_{'ssn'}}++ }
> for (qw/234-56-7890 0987-65-4321/) {
> print "Not found: $_\n" unless $SSN{$_}
> }


This way you build the hash from scratch each time you need it. It
won't save time over grep that way.

> but that's REALLY ugly (I don't like the creation of the intermediate
> %SSN hash). I would appreciate suggestions for a more elegant
> approach.


If you find you need the hash, build it along with the array @ARRAY,
so that it is always up to date. Then a fast lookup can decide if
a ssn is in the table or not.

Anno
 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      12-14-2003
geoffroy <(E-Mail Removed)> wrote:

> You can use this sub.



I doubt that.


> if($hashref->{'ssn'} eq $_[0]){retrun 1}

^^^^^^

What does the retrun() function do?



Have you seen the Posting Guidelines that are posted here frequently?


--
Tad McClellan SGML consulting
(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
geoffroy
Guest
Posts: n/a
 
      12-14-2003
David Filmer wrote:
> Suppose I have an array of hashes of names and social-security
> numbers:
>
> @ARRAY = (
> { first => 'John', last => 'Doe', ssn => '123-45-6789' },
> { first => 'Fred', last => 'Ree', ssn => '9876-54-321' }
> );
>
> Now suppose I want to print an error if any particular SSNs (say
> '234-56-7890' and '0987-65-4321') are not found in my @ARRAY.
> Obviously I can't just grep the array. I could build an intermediate
> hash (%SSN) like this:
>
> for (@ARRAY) { $SSN{$$_{'ssn'}}++ }
> for (qw/234-56-7890 0987-65-4321/) {
> print "Not found: $_\n" unless $SSN{$_}
> }
>
> but that's REALLY ugly (I don't like the creation of the intermediate
> %SSN hash). I would appreciate suggestions for a more elegant
> approach.



You can use this sub. it takes one parameter, the ssn.



sub does_ssn_exist{
foreach $hashref (@ARRAY){
if($hashref->{'ssn'} eq $_[0]){retrun 1}
}
return 0;
}


Geoffroy

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Array of Hashes in an array of hashes - Complicated! Matt Brooks Ruby 16 09-16-2009 05:53 PM
How to make an array of hashes to a single array with all thevalues of these hashes ? kazaam Ruby 12 09-13-2007 01:30 PM
using hashes as keys in hashes Steven Arnold Ruby 3 11-23-2005 03:25 PM
Hash of hashes, of hashes, of arrays of hashes Tim O'Donovan Perl Misc 5 10-28-2005 05:59 AM
In Search of Elegant Code - Change only the first null element in an array usenet@DavidFilmer.com Perl Misc 12 10-06-2005 03:14 PM



Advertisments