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

Want to sort the second column with reference/dereference

AA 34

AB 22

AC 12

#!/usr/bin/perl -w print "Please enter the file name: \n"; $file =<STDIN>; chomp $file; unless(open(FILE, $file)) { print "error opening file $file! \n"; exit; } @f=<FILE>; close FILE; $outputfile="sorted_ABA_2.5_nw"; unless(open(ABA, ">$outputfile")) { print "error opening file $outputfile \n"; exit; } foreach $line (@f) { @AB=split("\t", $line); #print "@AB"; #print "$AB[1]", "\t"; #print "$AB[2]"; @AA = sort{$a->[1] <=> $b->[1]} @AB; foreach $temp (@AA) { print "@$temp\t", "\n"; } } close ABA;

The program is not running and output shows the use of uninitalized value <=>.. Any solution..

Replies are listed 'Best First'.
Re: sorting first column
by davido (Cardinal) on Jul 19, 2013 at 06:21 UTC

    Once you take away what doesn't matter, and boil it down to a simplified test script, you're left with this:

    @f = <DATA>; foreach $line (@f) { @AB = split("\t", $line); @AA = sort { $a->[1] <=> $b->[1] } @AB; foreach $temp (@AA) { print "@$temp\t", "\n"; } } __DATA__ AA 34 AB 22 AC 12

    ...which indeed has the appearance of not running.

    If you modify the script to be strict compliant, you have this:

    use strict; use warnings; use diagnostics; my @f = <DATA>; foreach my $line (@f) { my @AB = split("\t", $line); my @AA = sort { $a->[1] <=> $b->[1] } @AB; foreach my $temp (@AA) { print "@$temp\t", "\n"; } } __DATA__ AA 34 AB 22 AC 12

    And when you run that, you get:

    Can't use string ("AA 34 ") as an ARRAY ref while "strict refs" in use at mytest.pl line 12, <D +ATA> line 3 (#1) (F) Only hard references are allowed by "strict refs". Symbolic references are disallowed. See perlref. Uncaught exception from user code: Can't use string ("AA 34 ") as an ARRAY ref while "strict refs" in use at mytest.pl line 12, <D +ATA> line 3. at mytest.pl line 12, <DATA> line 3.

    Now why might we be getting a "strict refs" violation? Probably because inside your sort routine, you're dereferencing elements of an array that don't hold a reference.

    Once you solve that, the next problem will be to sort rows based on columns, rather than columns based on columns.


    Dave

Re: sorting first column
by 2teez (Vicar) on Jul 19, 2013 at 06:13 UTC
    Something like this:
    use warnings; use strict; chomp(my @data_array=<DATA>); print join $/ => map{$_->[0]} sort{$a->[1] <=> $b->[1]} map{[$_,(split/\s+/,$_,2)[1]]} @data_array; __DATA__ AA 34 AB 22 AC 12
    ..produces..
    AC 12 AB 22 AA 34
    Update: And if the above is using too much power :), you can simply use a hash like so:
    my %hash; while(<DATA>){ next if /^\s*$/; my @data = split; $hash{$data[1]} = $data[0] } print $hash{$_},' ',$_,$/ for sort{$a<=>$b} keys %hash; __DATA__ AA 34 AB 22 AC 12
    Update 2: On the Hash method:
    Please note that the keys used in the hash must be UNIQUE for the hash method to work properly as intended.
    ww thanks for catching that.
    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me