0

I need to know the way of creating the associative array in Perl.

Basically, now I have the code which is implemented as follows:

 my $getEmployeeListOfTeamQuery  = "SELECT profiles.userid
                                  FROM user_group_map,profiles
                                  WHERE user_group_map.group_id = $teamId
                                  AND profiles.userid = user_group_map.user_id
                                  AND profiles.active = 'y'
                                  AND profiles.login_name NOT LIKE 'qa_%'
                                  AND profiles.disabledtext = ''
                                  GROUP BY profiles.login_name
                                  ORDER BY profiles.login_name";

    my $getEmployeeListOfTeam = $dbh->prepare($getEmployeeListOfTeamQuery);
    $getEmployeeListOfTeam -> execute();
    my @techs = ();

    while(my ($tech) - $getEmployeeListOfTeam->fetchrow_array) {
        push @techs,$tech;
    }

So the above code will be having the query in $getEmployeeListOfTeamQuery. It created the array names as techs.

Then I tried pushing the values into the array.

Here it is working fine.

My question here is regarding the creation of the associative array.

That is, I need to query as follows: "SELECT profiles.userid, profiles,username....."

Hence I need to create an associative array with "userid" as the key and "username" as the value.

7
  • You have to use ->fetchrow_hashref (instead of fetchrow_array). This way you obtain a ref to an associative array (hash) Commented Feb 14, 2016 at 9:13
  • Remember: given an hash ref $href you can use the syntax $href->{'key'} to get the value associated to 'key' Commented Feb 14, 2016 at 9:24
  • 2
    @frhack: If you read the question carefully, you will see that the OP is not asking for the data structure that fetchrow_hashref() returns. Commented Feb 14, 2016 at 10:59
  • 1
    @frhack: Read the question more closely. The key in the hash is one column from each row and the value is another. That is not what fetchrow_hashref() gives you. Using fetchrow_hashref() would give a data structure like { userid => "foo", username => "bar" }. The question asks for a structure like { foo => "bar"}. Commented Feb 15, 2016 at 10:45
  • 1
    ok ok ok .... sorry what a my mistake... I apologize !!! Please see my new answer. Commented Feb 15, 2016 at 13:35

4 Answers 4

4

I worry about the resources that you are using to learn Perl. Perl programmers haven't used the term "associative array" since Perl 5 was released over twenty years ago. We now call these structures "hashes". If you're learning from resources that use the term "associative array", then they are almost certainly horribly outdated.

But, to answer your question. The code is pretty simple.

my $sql = 'select profiles.userid, profiles.username...';
my $sth = $dbh->prepare($sql);
$sth->execute;

my %techs_hash;
while (my @row = $sth->fetchrow_array) {
  $techs_hash{$row[0]} = $row[1];
}
Sign up to request clarification or add additional context in comments.

2 Comments

Associative array is formal CS language, and it refers to that which the Perl "hash" is implementing (actually a hash table, I suppose). In formal CS language, hash refers to either the hash function itself or the output of a hash function, the hash value, not an associative array. I cannot really cite this, but a quick search on scholar.google.com or perusing some CS textbooks might yield quantitatively sufficient evidence that this information is true, and is not outdated by 20 years.
@JonathanKomar: I understand all of that. But my point stands that if you're using Perl resources that use the term, (unless they say something like "hashes are Perl's implementation of associative arrays") then they are likely to be rather outdated.
3

Use selectcol_arrayref() and the Columns attribute:

my $aref = $dbh->selectcol_arrayref('select userid, login_name ...', {Columns => [1, 2]});
my %hash = @$aref;

Comments

0

You can fetch all rows into hash of hashes by one call to selectall_hashref:

 my $tech=$dbh->selectall_hashref("select profile.userid, profiles.username, ...",'userid');

Or you can fetch all rows into array of hashes with selectall_arrayref with attribute {Slice=>{}}:

my $tech=$dbh->selectall_arrayref("select profile.userid, profiles.username, ...",{Slice=>{}});

And then turn it into desired hash (this is exactly what you want):

my $result;
$result->{$_->{userid}}=$_->{username} foreach @$tech;

3 Comments

Only the second option does what the question asked, and it's not very efficient with no additional benefit.
additional benefit here is a shorter code - why write those prepare execute while fetch things when they are already (and quite efficiently) implemented in selectall_* subs ?
"this is exactly what you want" - well, the question asks for a hash and you have given us a hash reference. Not sure that's "exactly what you want" :-) Perhaps my %result; $result{$_->{userid}}=$_->{username} foreach @$tech; would be a little closer :-)
0

Use:

my @l;
while(my $h = $sth->fetchrow_hashref) {
  push @l, $h;
}
my %hash;
map { $hash{$_->{userid}} = $_->{username} } @l;

5 Comments

Why not assign the hash inside the while loop? while (...) { $hash{$h->{userid}} = $h->{username}; }. Not sure why you'd want to add in that extra loop.
You are right but here I wanted propose a lambda style. The map function is one of the fundamental instrument. reactivex.io/learnrx
my %hash = map { $_->{userid} => $_->{username} } @{ $sth->fetchall_arrayref({}) };
@DaveCross perfect answer !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.