Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to loop on sorted (with custom sort) keys of a hash in Raku?

Tags:

raku

Trying to progressively convert some Perl scripts to Raku. I am quite stuck with the following one, even after browsing quite a lot here and reading Learning Perl 6 more deeply.

The part on which I can't make progress is the last loop (converted to for); getting keys and sorting them by month name and day number looks impossible, but I am sure it is doable.

Any hints on how to achieve this with "idiomatic" syntax would be really welcome.

#!/usr/bin/perl

use strict;

my %totals;

while (<>) {
    if (/redis/ and /Partial/) {
        my($f1, $f2) = split(' ');
        my $w = $f1 . ' ' . $f2;
        $totals{$w}++;
    }
}

my %m = ("jan" => 1, "feb" => 2, "mar" => 3, "apr" => 4, "may" => 5, "jun" => 6,
         "jul" => 7, "aug" => 8, "sep" => 9, "oct" => 10, "nov" => 11, "dec" => 12);

foreach my $e (sort { my($a1, $a2) = split(' ', $a) ; my($b1, $b2) = split(' ', $b) ;
            $m{lc $a1} <=> $m{lc $b1} or $a2 <=> $b2 } keys %totals) {
    print "$e", " ", $totals{$e}, "\n";
}
like image 666
user15795022 Avatar asked Apr 29 '21 16:04

user15795022


2 Answers

Fed with the same sample data, your perl code produces the same output as this.

my $data = q:to/END/; 
may 01 xxx3.1 Partial redis
may 01 xxx3.2 Partial redis
may 01 xxx3.3 Partial redis
apr 22 xxx2.2 Partial redis
apr 22 xxx2.1 Partial redis
mar 01 xxx1 redis Partial
some multi-line
string
END


sub sort-by( $value )
{
  state %m = <jan feb  mar apr may jun jul aug sep oct nov dec> Z=> 1..12;
  %m{ .[0].lc }, .[1] with $value.key.words;
}

say .key, ' ', .value.elems 
  for $data
    .lines
    .grep( /redis/ & /Partial/ )
    .classify( *.words[0..1].Str )
    .sort( &sort-by );
like image 105
Holli Avatar answered Oct 29 '22 11:10

Holli


You could try something like:

enum Month (jan => 1, |<feb mar apr may jun jul aug sep oct nov dec>);

lines()
andthen .grep: /redis/&/Partial/
andthen .map: *.words
andthen .map: {Month::{.[0].lc} => .[1].Int}\ 
#or andthen .map: {Date.new: year => Date.today.year, month =>  Month::{.[0].lc},  day => .[1], }\
andthen  bag $_
andthen .sort
andthen .map: *.put;
like image 31
wamba Avatar answered Oct 29 '22 12:10

wamba