How can I idiomatically access the first hash element of a single element in Perl?

I have a script that gets some data using DBI fetchall_hashref ().

It usually returns a hash, for example:

{ 1 => { id => 1 } } 

However, I am only interested in the value of the first item in the hash, which is the maximum value of a particular column. I know that Perl hashes are not ordered, but, fortunately, this particular request always returns exactly 1 or 0 records (since this is a MAX () request).

But the code currently in use is really ugly:

 $results->{(keys %{$results})[0]}->{'id'}; 

Is there a more elegant way to do this? (Without resorting to CPAN modules)

Explanation

I get a hash from the data access layer that we use in the house. Everything returns through fetchall_hashref (). I do not call fetchall_hashref () itself, this is how the data access functions are implemented internally, so they tell me. I am a consumer of this returned data, and this happens in the form of a hash. I'm looking for a more concise way, if one exists, to access query results with a single return value

+4
source share
5 answers

You can dereference the id key of the first value in %$results :

 (values %$results)[0]->{id}; 

Usually this will not be clearly defined , since the order of the values ​​returned by the keys or values may be different even between runs on the same computer using the same perl , but since you said that %$results can contain only one or zero element, this is a valid method.

+6
source

Instead of fetchall_hashref, if you only return rows 0/1, why not make selectrow_array or selectrow_hashref ?

+5
source

Why are you using fetchall_hashref to get a single value? This is best done using selectrow_array :

 my ($max) = $dbh->selectrow_array($sql); 

Update: if you cannot use another DBI method, a more concise way would be:

 my $val = [%$results]->[1]{id}; 
+5
source

Does your data access level support serial key hash? If so, what about

 $results->{1}{id} 

(Of course, this may not be so ... but your example data used key 1 for the first record, so it is possible that the data access level may use deterministic keys.)

+1
source
 my @keys = sort { $a <=> $b } keys %$results; my $first = $keys[0]; $results->{$first}->{id}; 

or if $ first = 1;

 $results->{1}->{id}; 
0
source

All Articles