Date: Tue, 04 Sep 2001 01:15:16 -0400 From: Benjamin Goldberg Subject: Re: AoH - continued Message-Id: <3B946364.43A1119F@earthlink.net> TuNNe|ing wrote: > > Yo, > Ok. I was able to comprehend all the goodies from my previous post , > except for Godzilla's stuff...but that's ok, my lurking teaches me > he/she just may be too smart for it's on good. > > I am quite sure I need the mapping and sort functions to accomplish my > goal, but I need references to a post or a document. I did a search in > google.groups and walked away feeling spanked. > > DATA is a _|_ delimited file with keys directly follwed by it's value. > I would like to be able to use the first line of my DATA as a way to > "sort " the rest of the data. So in this specific example the "print > @goods;" statement should be equivalent to print @goods = ("music", > "very good", "mp3" "video", "too long", "mpeg"); > [snip] my @data = map {chomp;+{split, /\|/}} ; # first line is category=>1, type=>3, info=>2. # remove it and create 1=>category, 3=>type, 2=>info. my %sortkeys = reverse %{shift @data}; # sort *numerically*, (1, 3, 2) to get (1, 2, 3). # then use (1, 2, 3) to get (category, info, type) my @sortkeys = @sortkeys{sort {$a <=> $b} keys %sortkeys}; # create the sortsub: sub { $a->{category} cmp $b->{category} || ... } my $sortkeys = join " || ", map "\$a->{$_} cmp \$b->{$_}", @sortkeys; my $sortsub = eval "sub { $sortkeys )"; my @sorted = sort $sortsub @data; #my @goods = map values %$_, @sorted; # orig code does this my @goods = map @$_{@sortkeys}, @sorted; # but what's wanted is this. > __DATA__ > category|1|type|3|info|2 > category|music|type|mp3|info|very good > category|video|info|too long|type|mpeg Be *very careful* about creating $sortsub. Since in your example, the data is gotten from *DATA, I assume that it is free of malicious content. In particular, I assume all keys are things which are valid barewords, and do not contain any spaces or other non-word characters. If they might contain such things, the code becomes: my $sortkeys = join " || ", map "\$a->{\$sortkeys[$_]} cmp \$b->{\$sortkeys[$_]}", 0..$#sortkeys; If your data comes from outside your script, as it might in the real world, then use a line like the one above. If you're generating html, you might want to replace the assignment to @goods with something like: print "\n"; print "", map "\n"; print "", map "\n" for @sorted; print "
$_", @sortkeys), "
", @$_{@sortkeys}, "
\n"; -- "I think not," said Descartes, and promptly disappeared.