http://qs321.pair.com?node_id=910868

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

Hi All, I am back with one more question. Please note that i am not asking for any ready made code here but just a few tips from the experts present here. So no cheating on my part,if anyone can offer help i will be thankful. As i am learning perl since 1 week now,so i have a question. I am writing into a file some values and am splitting it to get the second position say $F2. Now i want to print and sort the unique values of that field only. I don't care about the rest of the fields in my file. Just i want to print the $F2 in a unique and sorted manner.

Replies are listed 'Best First'.
Re: Perl sorting unique values
by Corion (Patriarch) on Jun 22, 2011 at 08:39 UTC
Re: Perl sorting unique values
by Utilitarian (Vicar) on Jun 22, 2011 at 08:43 UTC
    If ever you find yourself thinking "I need to get the unique values of $THING" you should consider using a hash, iterating through the values for $F[2] and incrementing $hash_of_f2{$F[2]} would give you a set of unique values available as keys %hash_of_f2 which you could then sort

    print "Good ",qw(night morning afternoon evening)[(localtime)[2]/6]," fellow monks."
      my %hash; open (FILE,"abc.txt"); while (<FILE>) { chomp; my ($key,$val) = split '\|'; print $hash{$val}; }
      This is a bit of code which i have written,i did not applied sort on it till now.But,its not working.

        Almost there:

        use strict; use warnings; my %hash; open my $fh, '<', 'abc.txt' or die $!; while (<$fh>) { chomp; my ($key, $val) = split '\|'; $hash{$val}++; } print "$_\n" for sort keys %hash;
Re: Perl sorting unique values
by Khen1950fx (Canon) on Jun 22, 2011 at 13:59 UTC
    You could examine $f2 with List::Uniq.
    #!/usr/bin/perl use strict; use warnings; use List::Uniq qw(:all); use Data::Dumper::Concise; my $f2 = [ qw|a c d b e d a|]; my $uniq = uniq( {sort => 1}, $f2 ); print Dumper($uniq);
Re: Perl sorting unique values
by rnaeye (Friar) on Jun 22, 2011 at 14:12 UTC

    If you are open to non-Perl solutions, I will recommend Unix cut and sort commands. They are very easy to use.

Re: Perl sorting unique values
by sundialsvc4 (Abbot) on Jun 22, 2011 at 15:55 UTC

    When you want to find the unique entries in (especially) a large collection of items, first you sort it, then you walk through the list to fetch the unique items.   (Thanks to the sort, all duplicate items are adjacent.)   You cannot, AFAIK, do this in just one step, unless the sort-utility or package that you are using provides that option.

    TMTOWTDI, of course.   Memory-based tricks such as hash-tables are certainly fine up to a point.   The sort-then-uniq strategy will handle data of any quantity and will do so with linear performance.

    Existing CPAN packages, as mentioned, are always to be looked-for first.   (No matter what you’re doing, it has been done before.)

      The sort-then-uniq strategy will handle data of any quantity and will do so with linear performance.

      When will you get it through your thick skull that sorting is not linear; it is O(N log N). And disk sorting slower still.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Hi All, I used wind's method but with slight modifications as below
        ##########################prints unique and sorted salary use strict; use warnings; my %hash; open my $fh, '<', 'abc.txt' or die $!; while (<$fh>) { chomp; my ($key, $val , $val1) = split '\|'; $hash{$val1}++; } print "$_\n" for sort keys %hash; ----abc.txt------ P|PERL|50000 Paa|JAVA|20000 Poo|VB|10000 AB|SAN|20000 ABCD|CSS|500 PQRS|HTML|200 --The output is-- 10000 200 20000 500 50000
        Though i sorted and printed the unique values,the issue is maybe we may want to print it like
        50000 20000 10000 500 200
        But according to "Perl in 21 days" sort only compares the first digit/letter and sorts accordingly. For printing the above specified output we may want to write a subroutine which compares two values and then swaps them and prints the output. And one more thing, we are not allowed to install CPAN modules in our firm,as we have restricted access.So whatever we do we have to use existing functions and code.