
rGeoffrey
User
/ Moderator
Jan 7, 2001, 9:21 PM
Post #3 of 7
(777 views)
|
In this case we cannot just do a simple sort, or even a simple sort {$a cmp $b} because we need to actually be sorting on things from the middle of the strings. This is a good time to use my favorite perl function, 'map', not just once, but twice, in a Schwartzian Transform. And because we need to filter the list down to just those that match the folder, we will throw in a grep also.
sub transform_sort { my ($folder, $option, @array) = @_; my %index = (Folder => 0, 'First name' => 1, Surname => 2, City => 3, Country => 4); return (map { (split ('<->', $_))[1] } sort map { join ('<->', lc ((split ('\|', $_))[$index{$option}]), $_) } grep (/^$folder\|/ , @array) ); } Inside the return you must read from bottom to top as each line takes an array as input and passes it on to the command above it. First grep takes the original @array and only passes on things that begin with $folder. Then the lower map finds the keyword that we want to search on and create an array of 'lc (keyword)<->original string'. Then these strings can pass through the normal boring everyday sort. And lastly we split on '<->' to get the original string back. If you want to try it youself, here is the rest of my test...
#Folder|First name|Surname|City|Country my @array = ('0|tom|smith|new york|usa', '1|tim|conway|paris|france', '2|mary|jones|chelsea|uk', '2|tina|butler|dublin|ireland', '3|frank|conway|berlin|germany', '3|michael|buckley|Cork|Ireland'); print ("\nThe original array is:\n ", join ("\n ", @array), "\nThe sorted array zanardi version:\n ", join ("\n ", sort {lc($a) cmp lc($b)} @array), "\nThe sorted array for (1, 'Surname')is:\n ", join ("\n ", &transform_sort (1, 'Surname', @array)), "\nThe sorted array for (2, 'Surname')is:\n ", join ("\n ", &transform_sort (2, 'Surname', @array)), "\nThe sorted array for (2, 'City')is:\n ", join ("\n ", &transform_sort (2, 'City', @array)), "\nThe sorted array for (2, 'First name')is:\n ", join ("\n ", &transform_sort (2, 'First name', @array)), "\nThe sorted array for (2, 'Country')is:\n ", join ("\n ", &transform_sort (2, 'Country', @array)), "\n\n");
|