On 2/10/06 Eric Lease Morgan wrote: >On Feb 10, 2006, at 3:51 PM, Jonathan Gorman wrote: >>> How do I loop through a reference to an array? >>> >>> I have the following data structure: >>> >>> my %facets = ( >>> 'audiences' => [('freshman', 'senior')], >>> 'subjects' => [('music', 'history')], >>> 'tools' => [('dictionaries', 'catalogs')] >>> ); >>> >>> foreach my $key (sort(keys(%facets))) { print $key, "\n" } >> >> Quick short answer, @{$facets{$key}}..so > > >Thank you for the quick responses. Tastes great; less filling. > >Now I'm going to make each value in the referenced array a reference >to a hash; I'm going to make my data structure deeper. 'More later.
Eric -- Then why use an array? Do you need to process things in a certain non-alphbetical order, such as 'dictionaries' before 'catalogs'? If you substitute references to hashes for the elements of your above arrays, you'll lose the names, and only have the order to go on for knowing what they contain. This: my %facets = ( 'audiences' => [('freshman', 'senior')], 'subjects' => [('music', 'history')], 'tools' => [('dictionaries', 'catalogs')] ); would become: my %facets = ( 'audiences' => [(\%freshman, \%senior)], 'subjects' => [(\%music, \%history)], 'tools' => [(\%dictionaries, \%catalogs)] ); but then you can't use those hash names for de-referencing the interior hashes. Oh, you just posted another question: >Since that worked so well, I'll ask this question. Given the >following data structure, how do I print out something like this: > > tools > dictionaries > websters - http://websters.com > oxford - http://oxford.edu > catalogs > und - http://catalog.nd.edu > worldcat - http://worldcat.com > > c> > >This code doesn't cut it: > > foreach my $key (sort(keys(%facets))) { > > print $key, "\n"; > > foreach my $term (@{$facets{$key}}) { > > print "\t", $term, "\n"; > > } > > } > This would work better (eliminate the arrays): my %facets = ( 'tools' => { 'dictionaries' => { 'websters' => 'http://websters.com', 'oxford' => 'http://oxford.edu' }, 'catalogs' => { 'und' => 'http://catalog.nd.edu', 'worldcat' => 'http://worldcat.com' }, }, # other elements of %facets ); # access my $wbstr_url = $facets{tools}->{dictionaries}->{websters}; # 'http://websters.com' my $wrldct_url = $facets{tools}->{catalogs}->{worldcat}; # 'http://worldcat.com' # iterate -- watch out for email line-breaking foreach my $facet_key (keys %facets) { foreach my $sub_key (keys %{ $facets{$facet_key} } ) { foreach my $inner_key (keys %{ $facets{$facet_key}->{$sub_key} } ) { print "$facet_key: $sub_key: $inner_key: $facets{$facet_key}->{$sub_key}->{$inner_key} \n"; } } } # prints: tools: catalogs: worldcat: http://worldcat.com tools: catalogs: und: http://catalog.nd.edu tools: dictionaries: oxford: http://oxford.edu tools: dictionaries: websters: http://websters.com That's not so easy to read, and very redundant as far as de-referencing. # iterate -- a little easier to keep track foreach my $facet_key (keys %facets) { my %sub_hash = %{ $facets{$facet_key} }; for my $sub_key (keys %sub_hash) { my %inner_hash = %{ $sub_hash{$sub_key} }; foreach my $inner_key (keys %inner_hash) { print "$facet_key: $sub_key: $inner_key: $inner_hash{$inner_key} \n"; } } } # prints: tools: dictionaries: oxford: http://oxford.edu tools: dictionaries: websters: http://websters.com tools: catalogs: worldcat: http://worldcat.com tools: catalogs: und: http://catalog.nd.edu Note that I didn't do any sorting in either of the above. Programming Perl's little chapter section on data structures is practically worthless unless you already understand nested references, which is what it's supposed to be explaining. It just makes your head spin. (My opinion, of course.) After years, it's easy to understand, but I don't use it to teach from. The main thing about multi-level data structures is to start from the innermost elements and work outward. Build outward each level only after you're sure you have the inner level down. If you use nested foreach()es against the keys of your nested hashes, use different names for the keys at each level. If you use arrays, remember that you gain order, but you may only refer to the elements by index, i.e., $array[0], array[1], etc. Finally, I find that in practice I rarely need to iterate through an entire nested structure and print or process every successive element. Usually I already know one or more of the inner hash keys. See my examples above labeled # access. Taking a lesson from Extreme Programming, write the routine that is supposed to do what you want, not a routine that just explores your data structure. Feed your data structure to your routine, and tweak until the correct result appears. Data::Dummper can also be a great help in seeing how your data structure is actually composed (although it sends warnings if any of your structure's sub-elements is a subroutine reference). Using the same %facets hash I built above, use Data::Dumper; print Dumper(\%facets); # note that's a reference to %facets #Prints: $VAR1 = { 'tools' => { 'catalogs' => { 'worldcat' => 'http://worldcat.com', 'und' => 'http://catalog.nd.edu' }, 'dictionaries' => { 'oxford' => 'http://oxford.edu', 'websters' => 'http://websters.com' } } }; [All code tested] HTH and Good luck, - Bruce __bruce__van_allen__santa_cruz__ca__