| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| Hi all, I have a category / subcategory file that looks like this cereal cereal:cold:cheerios cereal:cold:corn flakes cereal:hot atmealcereal:hot:cream of wheat bread bread:dakine sweet bread bread:wheat bread:white ....... Anyway you get the picture I read the file in and place into array of arrays open FILE, "$file"; my @file = (<FILE>); close FILE; my @a; foreach (@file){ my @line = split ':', $_; push (@a, \@line); } I want to put this into a hash of hashes where the last element would be equal to 1. something like this $cereal->{cold}->{cheerios} =1; or $bread->{wheat} = 1; if later on down the line the file changes so that there is more subcategories, the 1 would be replaced by a new hash like this $cereal->{cold}->{cheerios}->{regular} =1; $cereal->{cold->{cheerios}->{honeynut} = 1; I'm having trouble writing a function to do this. Any help or ideas would be appreciated |
|
#2
| |||
| |||
| Jeff wrote: > Hi all, > > I have a category / subcategory file that looks like this > > cereal > cereal:cold:cheerios > cereal:cold:corn flakes > cereal:hot atmeal> cereal:hot:cream of wheat > bread > bread:dakine sweet bread > bread:wheat > bread:white > > ...... Anyway you get the picture > > I read the file in and place into array of arrays > > open FILE, "$file"; > my @file = (<FILE>); > close FILE; > > my @a; > foreach (@file){ > my @line = split ':', $_; > push (@a, \@line); > } > > I want to put this into a hash of hashes where the last element would be > equal to 1. something like this > $cereal->{cold}->{cheerios} =1; > or $bread->{wheat} = 1; > > if later on down the line the file changes so that there is more > subcategories, the 1 would be replaced by a new hash like this > > $cereal->{cold}->{cheerios}->{regular} =1; > $cereal->{cold->{cheerios}->{honeynut} = 1; > > I'm having trouble writing a function to do this. > Any help or ideas would be appreciated The most obvious way of doing it is to use a recursive function (google "recursion") to walk the data structure each time a new item is inserted (ie for each new line). You probably want something a bit like this (insert_item is the recursive function, if that isn't obvious): mark@hermes:~$ cat cereal.pl #!/usr/bin/perl # use warnings; use strict; use Data: umper;my $root = {}; while(my $line = <DATA> ){ chomp $line; my @items = split /:/,$line; insert_item( $root, @items ); } print Dumper $root; sub insert_item { my $current = shift; my $nextkey = shift; my @items = @_; if(@items){ my $newsubtree; if(ref $current->{$nextkey}){ $newsubtree = $current->{ $nextkey }; }else{ $newsubtree = {}; $current->{ $nextkey } = $newsubtree; } insert_item( $newsubtree, @items ); }else{ $current->{ $nextkey } = 1; } } __END__ cereal cereal:cold:cheerios cereal:cold:corn flakes cereal:hot atmealcereal:hot:cream of wheat bread bread:dakine sweet bread bread:wheat bread:white mark@hermes:~$ perl cereal.pl $VAR1 = { 'bread' => { 'white' => 1, 'wheat' => 1, 'dakine sweet bread' => 1 }, 'cereal' => { 'cold' => { 'cheerios' => 1, 'corn flakes' => 1 }, 'hot' => { 'cream of wheat' => 1, 'oatmeal' => 1 } } }; Mark |
|
#3
| |||
| |||
| Thanks a million.. I learned something here and it's great Mark Clements wrote: > Jeff wrote: >> Hi all, >> >> I have a category / subcategory file that looks like this >> >> cereal >> cereal:cold:cheerios >> cereal:cold:corn flakes >> cereal:hot atmeal>> cereal:hot:cream of wheat >> bread >> bread:dakine sweet bread >> bread:wheat >> bread:white >> >> ...... Anyway you get the picture >> >> I read the file in and place into array of arrays >> >> open FILE, "$file"; >> my @file = (<FILE>); >> close FILE; >> >> my @a; >> foreach (@file){ >> my @line = split ':', $_; >> push (@a, \@line); >> } >> >> I want to put this into a hash of hashes where the last element would be >> equal to 1. something like this >> $cereal->{cold}->{cheerios} =1; >> or $bread->{wheat} = 1; >> >> if later on down the line the file changes so that there is more >> subcategories, the 1 would be replaced by a new hash like this >> >> $cereal->{cold}->{cheerios}->{regular} =1; >> $cereal->{cold->{cheerios}->{honeynut} = 1; >> >> I'm having trouble writing a function to do this. >> Any help or ideas would be appreciated > The most obvious way of doing it is to use a recursive function (google > "recursion") to walk the data structure each time a new item is inserted > (ie for each new line). You probably want something a bit like this > (insert_item is the recursive function, if that isn't obvious): > > mark@hermes:~$ cat cereal.pl > #!/usr/bin/perl > # > use warnings; > use strict; > > use Data: umper;> > my $root = {}; > > while(my $line = <DATA> ){ > chomp $line; > my @items = split /:/,$line; > > insert_item( $root, @items ); > } > > print Dumper $root; > > sub insert_item { > my $current = shift; > my $nextkey = shift; > my @items = @_; > > if(@items){ > my $newsubtree; > if(ref $current->{$nextkey}){ > $newsubtree = $current->{ $nextkey }; > }else{ > $newsubtree = {}; > $current->{ $nextkey } = $newsubtree; > } > insert_item( $newsubtree, @items ); > }else{ > $current->{ $nextkey } = 1; > } > } > > __END__ > cereal > cereal:cold:cheerios > cereal:cold:corn flakes > cereal:hot atmeal> cereal:hot:cream of wheat > bread > bread:dakine sweet bread > bread:wheat > bread:white > mark@hermes:~$ perl cereal.pl > $VAR1 = { > 'bread' => { > 'white' => 1, > 'wheat' => 1, > 'dakine sweet bread' => 1 > }, > 'cereal' => { > 'cold' => { > 'cheerios' => 1, > 'corn flakes' => 1 > }, > 'hot' => { > 'cream of wheat' => 1, > 'oatmeal' => 1 > } > } > }; > > > Mark > |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.