in reply to Using map function to print few elements of list returned by sort function

While I agree with boftx that a real script would be more appropriate for something like this in a production setting, I appreciate that pushing one-liners to their limits can make for good learning exercises.

As for your splice based solution, I think that's actually pretty good. Here are two small suggestions to tweak it further:

  1. You can get rid of the  BEGIN { $"=":" }  by using  $_  instead of  "@F"  to refer to the original line.

  2. You can get rid of the separate  %line  hash by adding that information directly to  %h  whose contents would then look like:
    ( ZM => [ [20470, "20470:ZM:Samfya:Africa"], [20149, "20149:ZM:Sesheke:Africa"], [18638, "18638:ZM:Siavonga:Africa"] ], ZW => [ ... ], ... )

Here's the one-liner with those changes, in a "scriptified" representation (which I find easier to work with; it's trivial to convert it back to the one-liner format by removing the lines with comments after them):

use warnings; # just for debugging use strict; # just for debugging my (%h, $k, @F); # just for debugging while (<>) { # -n chomp; # -l $\ = "\n"; # -l @F = split(':'); # -F":" -a push @{$h{ $F[1] }}, [$F[0], $_]; } for $k (sort keys %h) { print $_->[1] for splice [sort {$b->[0]<=>$a->[0]} @{$h{$k}}], 0, 4 } # -n

Replies are listed 'Best First'.
Re^2: Using map function to print few elements of list returned by sort function
by jaypal (Beadle) on May 25, 2014 at 14:55 UTC

    Thanks smls. That is indeed a very clever approach. My intension isn't to write the shortest code possible. The one-liner approach was just so that I can have a better understanding of perl built in functions.

    Your approach has just taught me that. Thank you for the detailed explanation.

Re^2: Using map function to print few elements of list returned by sort function
by jaypal (Beadle) on May 25, 2014 at 22:24 UTC

    Sorry to bug you with a follow up question. Is there a way we can nest two for loops in one line. For eg :

    for $k (sort keys %h) { print $_->[1] for splice [sort {$b->[0]<=>$a->[0]} @{$h{$k}}], 0, 4 }

    could be written something like:

    print $_->[1] for splice [sort {$b->[0]<=>$a->[0]} @{$h{$k}}], 0, 4 fo +r keys %h
      No, but you can chain maps.

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        With your hint, I was able to do the following

        perl -F':' -lane ' push @{$h{$F[1]}}, [$F[0],$_] }{ print $_->[1] for map { splice [sort {$b->[0] <=> $a->[0]} @{$h{$_}}], +0,4 } keys %h' file 20470:ZM:Samfya:Africa 20149:ZM:Sesheke:Africa 18638:ZM:Siavonga:Africa 699385:ZW:Bulawayo:Africa 61739:ZW:Chinhoyi:Africa 47294:ZW:Chegutu:Africa 37423:ZW:Bindura:Africa

        Thanks LanX, your guidance was much appreciated.

        Thanks LanX for the hint. Will try it out now.