Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl hash derived from array does not work as expected

Tags:

hash

perl

I am having some trouble with using hash derived from array. It fails "exists" test for elements I know that are there. I wrote small test code to confirm this. Here it is:

#!/usr/local/bin/perl

my @sieve = (2, 3, 5, 7, 11, 13, 17, 19);
my %sieve_hash = @sieve;


foreach $prime (@sieve) {
    if (exists($sieve_hash{$prime})) {
    print "$prime exists!\n";
    } else {
    print "$prime DOES NOT exist.\n";
    }
}

Here is sample output:

2 exists!
3 DOES NOT exist.
5 exists!
7 DOES NOT exist.
11 exists!
13 DOES NOT exist.
17 exists!
19 DOES NOT exist.

What am I doing wrong?

like image 727
mj6174 Avatar asked Apr 16 '26 03:04

mj6174


2 Answers

When assigning to a hash, a list of alternating keys and values are expected. The following would solve your problem:

my %sieve_hash = map { $_ => 1 } @sieve;

With the above, a simple truth test (rather than an existence test) would suffice. But since you're using an existence test, you could save some memory by using the following to assign undef instead of 1:

my %sieve_hash;
@sieve_hash{ @sieve } = ();

or

my %sieve_hash;
$sieve_hash{$_} = undef for @sieve;

I find a truth test much more elegant, though.

like image 98
ikegami Avatar answered Apr 17 '26 16:04

ikegami


When you assign an array to a hash, the even indexed elements, e.g. $sieve[0], $sieve[2] become the hash keys, the odd numbered elements $sieve[1], $sieve[3], etc become the hash values. You'll notice the pattern in your output where only every other element (the 0th, 2nd, 4th) "exists" as a key in the hash.

Use Data::Dumper to see what's going on:

#!/usr/bin/perl

use Data::Dumper;

my @sieve = (2, 3, 5, 7, 11, 13, 17, 19);
my %sieve_hash = @sieve;

print STDERR "Your array:\n";
print Dumper \@sieve;

print STDERR "Your hash:\n";
print Dumper \%sieve_hash;



Your array:
$VAR1 = [
          2,
          3,
          5,
          7,
          11,
          13,
          17,
          19
        ];
Your hash:
$VAR1 = {
          '11' => 13,
          '17' => 19,
          '2' => 3,
          '5' => 7
        };
like image 28
OneSolitaryNoob Avatar answered Apr 17 '26 16:04

OneSolitaryNoob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!