# I collected this rewrite over 6 months ago. More recently, I had reason to go # back and look at something very similar. When I did, I posted the question to # comp.lang.perl.moderated. # The answers I received seem to epitomize the essence of Fun With Perl # Original code $directory = '/tmp'; $file = '/tmp/foo'; @lines = ( '"a","b","/tmp","/tmp/foo","c","d","e","f","g","h","i"', '"z","y","/tmp","/tmp/foo","r","s","t","u","v","w","x"', ); foreach $line (@lines) { if ($line =~ m!"(.*)","(.*)","($directory)","($file)","(.*)","(.*)","(.*)","(.*)", "(.*)","(.*)","(.*)"!i) { $idnums{$i} = $i; $contactid{$i} = $1; $urls{$i} = $2; $states{$i} = $3; $regions{$i} = $4; $subregions{$i} = $5; $seealsos{$i} = $6; $listings{$i} = $7; $descriptions{$i} = $8; $cities{$i} = $9; $names{$i} = $10; $linkurls{$i} = $11; print "line: $line\n"; print "\$i $i\n"; $i++; } } # Rewrite: $i = 0; foreach $line (@lines) { if ($line =~ m/".*,"$directory","$file".*$/) { ($contactid{$i}, $url{$i}, $state{$i}, $region{$i}, $subregion{$i}, $sealso{$i}, $listing{$i}, $descriptions{$i}, $city{$i}, $name{$i}, $linkurl{$i}) = split(/","/,$line); # handle extra " $contactid{$i} =~ s/^"//; $linkurl{$i} =~ s/"$//; print "line: $line\n"; print "\$i $i\n"; $i++; } } # It's still much too clumsy. So I asked comp.lang.perl.moderated for a more # Perlish WTDI: Date: Fri, 30 Apr 1999 17:52:33 -0700 Subject: Seeking another WTDI Newsgroups: comp.lang.perl.moderated Suppose you have a flat file data file, where the fields are interesting, e.g. an address file: Brown, Vicki, PO Box 1269, San Bruno, CA, 94066 and you want to read that file, break each line into fields, and store the fields in an array $i = 0; while(<READ>) { $last[$i], $first[$i], $address[$i], $city[$i], $state[$i], $zip[$i] = split(/, /); } Is there a slicker WTDI? I feel like there should be some cool & nifty Perlish way, e.g. put all the field names (which become the array names) into an array of their own and then use map or somesuch to magically split the record into the right pieces and then bump the counter. @names = qw(last first address city state zip); and then do something magical with @names and split... To: clpm@lists.eyrie.org Newsgroups: comp.lang.perl.moderated Subject: Re: Seeking another WTDI I'd flip it the other way around: while (<READ>) { chomp; my %item; @item{qw(last first address city state zip)} = split /, /; push @data, \%item; } Then to get to the state of the 475'th user, it's $data[475]{state}. Date: Sat, 01 May 1999 00:16:06 -0400 Newsgroups: comp.lang.perl.moderated This code assumes the field names come from the first record, which happens occasionally. #!/usr/local/bin/perl -w use strict; my %struct; $_ = <DATA>; chomp; my @names = split /, /; while(<DATA>) { chomp; my @fields = split /, /; my $i = 0; foreach (@fields) { push @{ $struct{ $names[$i++] } }, $_; } } That'll create a hash of arrays which I think is what you want. You could also create an array of hashes (structs). while(<DATA>) { chomp; my %fields; @fields{ @names } = split /, /; push @structs, \%fields; } -- -- |\ _,,,---,,_ Vicki Brown <vlb@cfcl.com> ZZZzz /,`.-'`' -. ;-;;,_ Journeyman Sourceror: Scripts & Philtres |,4- ) )-,_. ,\ ( `'-' P.O. Box 1269 San Bruno CA 94066 '---''(_/--' `-'\_) http://www.cfcl.com/~vlb http://www.macperl.org ==== Want to unsubscribe from this list? (Don't you love us anymore?) ==== Well, if you insist... Send mail with body "unsubscribe" to ==== fwp-request@technofile.org </x-flowed>