Re: dereferencing an array - Pt 2
Short answer: $profit{ $facet }{ $term }{ $resource } = $url; Example: #!perl use strict; use warnings; use Data::Dumper; $Data::Dumper::Terse++; $Data::Dumper::Indent--; my %profit; while( DATA ) { chomp; my( $resource, $url, $term, $facet ) = split /,/; $profit{ $facet }{ $term }{ $resource } = $url; } print Dumper \%profit; __DATA__ asto magazine,http://oxford.edu,astronomy,subjects stars r us,http://websters.com,astronomy,subjects telescope world,http://telescope.com,astronomy,subjects 2 + 2 = 4,http://catalog.nd.edu,mathematics,subjects math library,http://worldcat.com,mathematics,subjects und,http://catalog.nd.edu,catalogs,tools worldcat,http://worldcat.com,catalogs,tools websters,http://websters.com,dictionaries,tools oxford,http://oxford.edu,dictionaries,tools On 2/10/06, Eric Lease Morgan [EMAIL PROTECTED] wrote: On Feb 10, 2006, at 5:41 PM, Bruce Van Allen wrote: foreach my $facet_key (keys %facets) { print $facet_key\n; my %sub_hash= %{ $facets{$facet_key} }; foreach my $sub_key (keys %sub_hash) { print \t$sub_key\n; my %inner_hash= %{ $sub_hash{$sub_key} }; foreach my $inner_key (keys %inner_hash) { print \t\t$inner_key - $inner_hash{$inner_key}\n; } } } This has been VERY helpful, and I appreciate the assistance. Now I need to programatically build the hash. I have this sample data structure: my %profile = ( 'subjects' = { 'astronomy' = { 'telescope world' = 'http://telescope.com', 'stars r us' = 'http://websters.com', 'asto magazine' = 'http://oxford.edu' }, 'mathematics' = { '2 + 2 = 4' = 'http://catalog.nd.edu', 'math library' = 'http://worldcat.com' } }, 'tools' = { 'dictionaries' = { 'websters' = 'http://websters.com', 'oxford' = 'http://oxford.edu' }, 'catalogs' = { 'und' = 'http://catalog.nd.edu', 'worldcat' = 'http://worldcat.com' } } ); I use the followign code, based on the good work of Bruce, to traverse %profile and output a set of nested HTML lists. It works for any size of %profile. Fun! print ul; foreach my $facet (sort(keys(%profile))) { print li$facet; my %facets = %{$profile{$facet}}; print ul; foreach my $term (sort(keys(%{$profile{$facet}}))) { print li$term; my %terms = %{$facets{$term}}; print ol; foreach my $resource (sort(keys(%terms))) { print lia href='$facets{$term}{$resource}'$resource/ a/li; } print /ol; print /li; } print /ul; print /li; } print /ul; I now need to build %profile programatically. As I loop through a set of information resources I can determine the following values: 1. resource name (ex: telescope world) 2. URL (ex: http://telescope.com) 3. term (ex: astronomy) 4. facet (ex: subjects) Given these values, how can I build %profile? -- Eric Perl Data Structures !R My Forte Morgan
Re: dereferencing an array - Pt 2
On Feb 11, 2006, at 8:16 AM, Brad Baxter wrote: I have this sample data structure: my %profile = ( 'subjects' = { 'astronomy' = { 'telescope world' = 'http://telescope.com', 'stars r us' = 'http://websters.com', 'asto magazine' = 'http://oxford.edu' }, 'mathematics' = { '2 + 2 = 4' = 'http://catalog.nd.edu', 'math library' = 'http://worldcat.com' } }, 'tools' = { 'dictionaries' = { 'websters' = 'http://websters.com', 'oxford' = 'http://oxford.edu' }, 'catalogs' = { 'und' = 'http://catalog.nd.edu', 'worldcat' = 'http://worldcat.com' } } ); I now need to build %profile programatically. As I loop through a set of information resources I can determine the following values: 1. resource name (ex: telescope world) 2. URL (ex: http://telescope.com) 3. term (ex: astronomy) 4. facet (ex: subjects) Given these values, how can I build %profile? Short answer: $profile{ $facet }{ $term }{ $resource } = $url; Wow! Perfect!! I have been able to take what Jonathan Gorman, Bruce Van Allen, and Brad Baxter have given me and incorporate it into a the beginnings of a patron-specific interface of MyLibrary. In MyLibrary patrons can be created and cataloged with facet/term combinations -- a controlled vocabulary. These same facet/term combinations are used to catalog information resources. Thus, through the controlled vocabulary I am able to create relationships between resources and patrons. The results is the display of a set of information resources designed for individuals with particular characteristics. For example, try the following URLs. Each points to a different patron with different characteristics, and each page provides the ability to display the information resources in an alphabetical or grouped view: * Andrew Carnegie http://dewey.library.nd.edu/morgan/portal/?cmd=patronid=194 * Leonardo D'Vinci http://dewey.library.nd.edu/morgan/portal/?cmd=patronid=191 * Galileo Galilei http://dewey.library.nd.edu/morgan/portal/?cmd=patronid=193 Thanks guys. I have added your names to my code. -- Eric Morgan
dereferencing an array
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')] ); I can use this code to get the keys for %facets: foreach my $key (sort(keys(%facets))) { print $key, \n } But since $key points to the reference of an array, I don't know how to loop through the referenced array. -- Eric Lease Morgan Head, Digital Access and Information Architecture Department University Libraries of Notre Dame (574) 631-8604
Re: dereferencing an array
foreach my $key1 (sort(keys(%facets))) { foreach my $key2 (sort(keys(%facets{$key1))) { print $key1 / $key2 \n; } } Spencer On 2/10/06, Eric Lease Morgan [EMAIL PROTECTED] 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')] ); I can use this code to get the keys for %facets: foreach my $key (sort(keys(%facets))) { print $key, \n } But since $key points to the reference of an array, I don't know how to loop through the referenced array. -- Eric Lease Morgan Head, Digital Access and Information Architecture Department University Libraries of Notre Dame (574) 631-8604 -- Spencer M. Anspach, Library Systems Analyst/Programmer Library Information Technology, Indiana University Library E456 phone: (812) 856-5318 Bloomington, IN 47405 fax: (812) 856-4979 [EMAIL PROTECTED] pager: (812) 335-7403
Re: dereferencing an array
Ergg, just realized my copy of Programming Perl is at home. Ah well, the old noggin is pretty sure how to do this. Quick short answer, @{$facets{$key}}..so foreach $foo (@{$facets{$key}}) { print Hello, I'm $foo. Pleased to meet ya.\n; } or something along those lines Jonathan T. Gorman Visiting Research Information Specialist University of Illinois at Champaign-Urbana 216 Main Library - MC522 1408 West Gregory Drive Urbana, IL 61801 Phone: (217) 244-4688 On Fri, 10 Feb 2006, Eric Lease Morgan 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')] ); I can use this code to get the keys for %facets: foreach my $key (sort(keys(%facets))) { print $key, \n } But since $key points to the reference of an array, I don't know how to loop through the referenced array. -- Eric Lease Morgan Head, Digital Access and Information Architecture Department University Libraries of Notre Dame (574) 631-8604
Re: dereferencing an array
On Feb 10, 2006, at 3:58 PM, Eric Lease Morgan wrote: 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. 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 my %facets = ( 'tools' = [( 'dictionaries' = [( 'websters' = 'http://websters.com', 'oxford' = 'http://oxford.edu' )], 'catalogs' = [( 'und' = 'http://catalog.nd.edu', 'worldcat' = 'http://worldcat.com' )] )] ); This code doesn't cut it: foreach my $key (sort(keys(%facets))) { print $key, \n; foreach my $term (@{$facets{$key}}) { print \t, $term, \n; } } Is my data structure dumb? -- Eric Morgan
Re: dereferencing an array
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
Re: dereferencing an array - Pt 2
My previous message got kinda long, so here's some tested Perl that does just what Eric's last message asked for: #!/usr/bin/perl -w use strict; 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 ); # iterate foreach my $facet_key (keys %facets) { print $facet_key\n; my %sub_hash= %{ $facets{$facet_key} }; foreach my $sub_key (keys %sub_hash) { print \t$sub_key\n; my %inner_hash= %{ $sub_hash{$sub_key} }; foreach my $inner_key (keys %inner_hash) { print \t\t$inner_key - $inner_hash{$inner_key}\n; } } } __END__ # prints: tools dictionaries oxford - http://oxford.edu websters - http://websters.com catalogs worldcat - http://worldcat.com und - http://catalog.nd.edu - Bruce __bruce__van_allen__santa_cruz__ca__
Re: dereferencing an array - Pt 2
On Feb 10, 2006, at 5:41 PM, Bruce Van Allen wrote: foreach my $facet_key (keys %facets) { print $facet_key\n; my %sub_hash= %{ $facets{$facet_key} }; foreach my $sub_key (keys %sub_hash) { print \t$sub_key\n; my %inner_hash= %{ $sub_hash{$sub_key} }; foreach my $inner_key (keys %inner_hash) { print \t\t$inner_key - $inner_hash{$inner_key}\n; } } } This has been VERY helpful, and I appreciate the assistance. Now I need to programatically build the hash. I have this sample data structure: my %profile = ( 'subjects' = { 'astronomy' = { 'telescope world' = 'http://telescope.com', 'stars r us' = 'http://websters.com', 'asto magazine' = 'http://oxford.edu' }, 'mathematics' = { '2 + 2 = 4' = 'http://catalog.nd.edu', 'math library' = 'http://worldcat.com' } }, 'tools' = { 'dictionaries' = { 'websters' = 'http://websters.com', 'oxford' = 'http://oxford.edu' }, 'catalogs' = { 'und' = 'http://catalog.nd.edu', 'worldcat' = 'http://worldcat.com' } } ); I use the followign code, based on the good work of Bruce, to traverse %profile and output a set of nested HTML lists. It works for any size of %profile. Fun! print ul; foreach my $facet (sort(keys(%profile))) { print li$facet; my %facets = %{$profile{$facet}}; print ul; foreach my $term (sort(keys(%{$profile{$facet}}))) { print li$term; my %terms = %{$facets{$term}}; print ol; foreach my $resource (sort(keys(%terms))) { print lia href='$facets{$term}{$resource}'$resource/ a/li; } print /ol; print /li; } print /ul; print /li; } print /ul; I now need to build %profile programatically. As I loop through a set of information resources I can determine the following values: 1. resource name (ex: telescope world) 2. URL (ex: http://telescope.com) 3. term (ex: astronomy) 4. facet (ex: subjects) Given these values, how can I build %profile? -- Eric Perl Data Structures !R My Forte Morgan