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

Hello Monks,

I have file as follow

10,20
30,10
20,70
70,80
40,90
90,100
50,50

I want to split the file though comma separator and sort the file like

10,10
20,20
30,50
40,70
50,80
70,90
90,100

I wrote this program
open(FH,"abc1") or die "not open"; while(<FH>) { my($val1,$val2) = split(/,/,$_); push @record,[$val1,$val2]; } close(FH); my @sorted = sort {$a->[0] <=> $b->[0]} @record; foreach my $rec (@sorted) { print "$rec->[0],$rec->[1]"; }
This program is sorting only $val1 not $val2. How I can sort $val1, $val2 together.

Any help will be appreciated

Farhan

Replies are listed 'Best First'.
Re: Sorting Issue
by GrandFather (Saint) on Jul 27, 2006 at 10:27 UTC

    You need to sort the two columns independently then put them back together. Note that the following code assumes that both columns contain the same number of entries:

    use warnings; use strict; my @firsts; my @seconds; while(<DATA>) { chomp; my($val1,$val2) = split /,/; push @firsts, $val1; push @seconds, $val2; } @firsts = sort {$a <=> $b} @firsts; @seconds = sort {$a <=> $b} @seconds; my @sorted; push @sorted, [$firsts[$_], $seconds[$_]] for 0..$#firsts; print "$_->[0], $_->[1]\n" for @sorted; __DATA__ 10,20 30,10 20,70 70,80 40,90 90,100 50,50

    Prints:

    10, 10 20, 20 30, 50 40, 70 50, 80 70, 90 90, 100

    DWIM is Perl's answer to Gödel
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Sorting Issue
by Velaki (Chaplain) on Jul 27, 2006 at 10:34 UTC

    It looks like you're trying to sort the columns independently, and then recombine them visually.

    The following produces the results you desire, although it assumes that the left and right columns are the same length.

    #!/usr/bin/perl use strict; use warnings; my (@left, @right); while(<DATA>) { chomp; my ($left, $right) = split /,/; push(@left, $left); push(@right, $right); } @left = sort { $a <=> $b } @left; @right = sort { $a <=> $b } @right; print "$left[$_],$right[$_]\n" for 0 .. $#left; __DATA__ 10,20 30,10 20,70 70,80 40,90 90,100 50,50

    Hope this helped,
    -v.

    "Perl. There is no substitute."
      Hello Monks,

      Thanks you Guys. It is an excellent forum. I was not expecting prompt reponse.

      Thanks,
      Farhan
Re: Sorting Issue
by Hue-Bond (Priest) on Jul 27, 2006 at 10:17 UTC

    Since your requirements about the output are a bit vague, the output of this isn't exactly the same as yours. This outputs two columns of sorted numbers, and the right number of each column is never less than the number on its left.

    open my $fd, '<', 'file' or die "open: $!"; my @all; while (<$fd>) { chomp; push @all, split /,/; } close $fd; @all = sort { $a <=> $b } @all; my @result; for (my $i = 0; $i < @all; $i+=2) { push @result, "$all[$i]," . ( defined $all[$i+1] ? $all[$i+1] : '' ); } print "$_\n" for @result;

    --
    David Serrano

Re: Sorting Issue
by rodion (Chaplain) on Jul 27, 2006 at 10:23 UTC
    Are you saying you want to sort the numbers as if they are one long list, then put them back in pairs? For that the following should do what you want.
    my @record; open(FH,"abc1") or die "not open"; while (<FH>) { chomp; push @record,split(/,/,$_); } for my $idx (0..$#record) { if ($idx % 2) { print $record[$idx],"\n"; } else { print $record[$idx],","; }
Re: Sorting Issue
by johngg (Canon) on Jul 27, 2006 at 13:49 UTC
    In the spirit of TIMTOWTDI, here's yet another way. A kind of slurp into split into sort, all wrapped in a printing subroutine.

    use strict; use warnings; { local $/; printInTwos( sort {$a <=> $b} split m{(?:,|\s+)}, <DATA>); } sub printInTwos { print(shift, q{,}, shift, qq{\n}) while @_; } __END__ 10,20 30,10 20,70 70,80 40,90 90,100 50,50

    The output is

    10,10 20,20 30,40 50,50 70,70 80,90 90,100

    Cheers,

    JohnGG

    Update: I've just re-read the OP and realised I totaly misunderstood the requirement. Please ignore this post.

Re: Sorting Issue
by Moron (Curate) on Jul 27, 2006 at 12:30 UTC
    A two hash approach:
    my ( @hashes ) = ({},{}); while(<>) { chomp; @_=split /\,/; $hashes[$_]{$_[$_]} = 1 for (0..1); } @_=sort keys %{$hashes[1]}; print "$_," . shift(@_) . "\n" for sort keys %{$hashes[0]}

    -M

    Free your mind