http://www.perlmonks.org?node_id=458515

texuser74 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks

I want to do two types of sorting in the follwoing input data, e.g.

Input:<test.in> Xu, Guo Qin B-5-OR9 Zhang, Yong Ping B-5-OR10 Xu, Guo Qin B-5-OR10 Tsuneyuki, Shinji B-6-IN11 Xu, Guo Qin B-6-IN12
1st sort: Sort the names, and then combine them:
open(IN, '<', "test.in"); open(OUT, '>', "test.out"); while (<IN>) { chomp; next unless /\S/; my ($name, $num) = /(.*)\s+(B-.*)/; $data{$name}{$num} = 1; } foreach my $name (sort keys %data) { print OUT "$name "; print OUT join ', ', sort { $a cmp $b } keys %{$data{$name}}; print OUT "\n\n"; } output: Tsuneyuki, Shinji B-6-IN11 Xu, Guo Qin B-5-OR10, B-5-OR9, B-6-IN12 Zhang, Yong Ping B-5-OR10
2nd Sort: This is where i am having problem, now i want to sort the codes numerically inside each name, i.e. the required output is
Tsuneyuki, Shinji B-6-IN11 Xu, Guo Qin B-5-OR9, B-5-OR10, B-6-IN12 Zhang, Yong Ping B-5-OR10
please help me in doing this.

best regards,
raj

Replies are listed 'Best First'.
Re: difficulty in multi sorting
by jdporter (Paladin) on May 19, 2005 at 04:55 UTC
    So the essence of your problem is how to sort these funky codes. Well, it would help if you could give a precise definition of their format, rather than making us guess. I'm guessing that the first number (the 5 and 6 in your examples) could be more than one digit wide, and that there are always exactly two capital letters in the third part.
    sub codes_sorted { # do the GRT dance map { substr $_, 10 } sort map { /-(\d+)-([A-Z]{2})(\d+)/; pack('N',$1).$2.pack('N',$3).$_ } }
    Then you can do
    print OUT join ', ', codes_sorted( keys %{$data{$name}} );
Re: difficulty in multi sorting
by pelagic (Priest) on May 19, 2005 at 06:34 UTC
    texuser74,
    you probably want to get the data into some structure before processing it. So why don't you read through your file and 'feed' a Hash of Array in a way like:
    ... my %hash; while (<IN>) { my $name = ... my $code = ... push @{ $hash{$name} }, $code; }
    Then you can loop through the sorted hash keys and print the name together with all it's (sorted) codes.
    foreach my $name (sort keys %hash) { print join (', ', $name, sort @{ $hash{$name} }), "\n"; }
    That's some sort of pseudo code, so it will not work as is. .. ;)

    pelagic