Re: Basic Array Question
by japhy (Canon) on May 10, 2006 at 15:39 UTC
|
Perl calls "associative arrays" hashes. It makes sense and it saves you a bunch of syllables to use at a later date. Anyway, you set a key-value pair in a hash this way: $hash{$key} = $value; Therefore, if your array, @row, has two elements, and you want the first field to be the key and the second field to be the value, you would do: $frequency{$row[0]} = $row[1];
In fact, you might want to use more descriptive names in your while statement:
my %freq;
while (my ($page, $hits) = $cursor->fetchrow_array) {
$freq{$page} = $hits;
}
| [reply] [d/l] [select] |
|
|
Perl calls "associative arrays" hashes. It makes sense and it saves you a bunch of syllables to use at a later date.
Yes to the latter, maybe to the former. The fact that associative arrays in perl are implemented using a hashing mechanism, is just an implementation detail that has no influence on how people use them. So I'm more or less unhappy with that name.
I'd prefer "string-indexed arrays" any day, but of course, people with find that name too long, too.
| [reply] |
|
|
I wouldn't mind "map" (except that's overloaded) or "mapping", and Python calls them (or at least used to call them) "dictionaries", which also makes sense (except you tend to think of a dictionary as being sorted alphabetically).
| [reply] |
|
|
while (@_ = $cursor->fetchrow) {
$freq{$_[0]}=$_[1];
}
What happens is you are associating the result to an anonymous array (@_) | [reply] [d/l] |
Re: Basic Array Question
by McDarren (Abbot) on May 10, 2006 at 15:42 UTC
|
Instead of doing @row =, I'd use explicitly named variables. Then the following will probably be easier to follow...
my %page_hits;
while (my ($page_title, $hit_count) = $cursor->fetchrow_array) {
$page_hits{$page_title} = $hit_count;
}
Cheers,
Darren :) | [reply] [d/l] [select] |
|
|
while (my ($page_title, $hit_count) = $cursor->fetchrow_array) {
I assume the next line is setting the page_hits hash, with the index being $page_title and the value being $hit_count, right?
Next dumb question, what is the '%' in front of the page_hits?, and why use 'my'?
Sorry for the ignorance , this is certainly not PHP :) | [reply] [d/l] |
|
|
The % tells perl that it is a hash (not a regular array, @, or a scalar, $). In perl, %var is different than $var is different than @var. So you can have all three if you want.
"my" declares a lexical scope. You should really read up on "use strict" "use warnings" and scoping. There are tons of articles on the web and on this site.
In regards to this specific use of "my" - it makes the two variables visible to only the inside of said while loop. If you have on "strict" and "warnings" and you try to print $page_title AFTER the end of the while loop, you will get an error, because the variable has gone out of scope.
It's not like PHP where you can make a variable inside a huge nested loop/function and have it visible outside of said loop or function.
| [reply] |
Re: Basic Array Question
by PreferredUserName (Pilgrim) on May 10, 2006 at 15:54 UTC
|
You can also get a hash back for each row, which
is handy if you're pulling a lot of fields that you
don't want to have to name explicitly in the fetch:
my %page_hits;
while (my $row = $cursor->fetchrow_hashref) {
$page_hits{$row->{page_title}} = $row->{hit_count};
}
The $HASH_REF->{KEY_NAME} syntax is used
to access elements via the row hash reference. | [reply] [d/l] [select] |
Re: Basic Array Question
by wazzuteke (Hermit) on May 10, 2006 at 16:38 UTC
|
As a side note, you may want to also lookinto the DBI::fetchrow_arrayref() whereas having DBI return a reference to an array rather than a copy of the extraced array has tended to be faster. You can think of it in the light of having DBI return a pointer to the particular segment of memory where the data is rather than returning all the data in memory.
The only change you would have to make, in this example (rather than re-naming the method call) would be to de-reference the array reference as you are looking to use the values within it. Therefore you could:
# Assuming you like the idea of scoping two variables
# lexically within the while block as noted in previous
# comments
while ( my ( $page_title, $hit_count ) = @{ $cursor->fetchrow_arrayref
+() } ) {
$page_hits{$page_title} = $hit_count;
}
You will see that the supplimental change to the logic would be the addition of the @{} block, telling Perl to de-reference the array reference returned from fetchrow_arrayref
Not a big deal, in most (some) cases, but certainly something to think about.
print map{chr}(45,45,104,97,124,124,116,97,45,45);
... and I probably posted this while I was at work => whitepages.com | inc.
| [reply] [d/l] [select] |
|
|
Wouldn't using fetchrow_arrayref, then immediately enclosing it in an @{} defeat the purpose of getting and array ref in the first place?
while ( my $ref = $cursor->fetchrow_arrayref ) {
$page_hits{$ref->[0]} = $ref->[1];
}
| [reply] [d/l] |
Re: Basic Array Question
by ptum (Priest) on May 10, 2006 at 16:26 UTC
|
In the special case where I have a select statement that will return key/value pairs, I usually use this syntax:
use strict;
use warnings;
# I assume you have already established your database handle
my $statement = "select my_key, my_value from my_table";
my $ary_ref = $db_handle->selectcol_arrayref($statement, { Columns=>
+[1,2] });
if ($DBI::errstr) {
#do something
}
my %lookup_table = @$ary_ref if ref($ary_ref) eq 'ARRAY';
This has the happy result of creating a reference to an array which can be treated as a series of key/value pairs, and thus can directly populate my hash table. I think it is a nice, readable shortcut.
No good deed goes unpunished. -- (attributed to) Oscar Wilde
| [reply] [d/l] |
Re: Basic Array Question
by Anonymous Monk on May 10, 2006 at 17:34 UTC
|
mindblowing stuff :)
can someone pass the aspirin
:)
would anyone be able to anwser my 2 daft questions from earlier too please?, the ones about my and %
Thanks for all your help
| [reply] |
|
|
@ is a sigil, indicating an array. $ is a sigil indicating a scalar. % is a sigil indicating a hash (an associative array).
- $variable is a scalar.
- @variable is an array.
- %variable is a hash.
my creates a lexically scoped variable.
Important: You won't be able to just guess at this stuff. perlintro is required reading, if you plan to actually hammer out a few lines of Perl code.
| [reply] |
|
|
Thanks, don't get me wrong -I am heavily reading up on all of this, its just that I'm jumping straight into a minor project in order to force myself to learn. I'm reading O'Riellys Llama book, and I'm only on chapter 4. I notice if I had reached chapter 6 I would have answered my hashes questions.
Thanks for answering my extremely fundamental questions.
I appreciate that there are security considerations also, but at present I'm just ploughing through code, making things clearer as I go.
| [reply] |
|
|
|
|