in reply to Re: sorting logfiles by timestamp
in thread sorting logfiles by timestamp

OK, I finally got a chance to try this. It works a treat, but I cannot for the life of me wrap my head around how and why, and I hate using code I can't understand (for several reasons). I'm OK until:

print "$_,$key" for map { $_->[1] } sort { $a->[0] <=> $b->[0] } map { [ split /:/, $myHash{$key}{info}[$_], 2 ] } 0 .. $#{$myHash{$key}{info}};

Is there a way to write that as a more C-style for loop, even if it's pseudo-code, or is that the only way it will work? I don't follow the flow as-is, and my attempt to rewrite it ended up with only printing indices of the array. I'm also having trouble following the map { } statements, but hopefully if I can grok the way the loop is working the rest will start to make a little more sense.

Thanks again.

Replies are listed 'Best First'.
Re^3: sorting logfiles by timestamp
by kcott (Archbishop) on Jan 23, 2014 at 14:43 UTC
    "It works a treat, but I cannot for the life of me wrap my head around how and why, and I hate using code I can't understand (for several reasons)."

    Firstly, I'm glad to hear you're not just blindly plugging in code you don't understand.

    The "map {} sort {} map {}" construct is known as the "Schwartzian Transform" (to which Laurent_R referred earlier in this thread).

    Where you encounter combinations of functions which take a list and return a list (e.g. grep, map, sort, etc.), it's often best to evaluate them in reverse order.

    Consider this (clunky) rewrite of that piece of code:

    my @indices_of_myhash_key_info_array = 0 .. $#{$myHash{$key}{info}}; my @two_element_arrayrefs_with_sortkey_and_data = map { [ split /:/, $myHash{$key}{info}[$_], 2 ] } @indices_of_myhash_key_info_array; my @two_element_arrayrefs_sorted_by_sortkey = sort { $a->[0] <=> $b->[0] } @two_element_arrayrefs_with_sortkey_and_data; my @data_element_only_sorted_by_sortkey = map { $_->[1] } @two_element_arrayrefs_sorted_by_sortkey; for (@data_element_only_sorted_by_sortkey) { print "$_,$key"; }

    Hopefully that explains what is going on but feel free to ask if anything needs further explanation.

    -- Ken