http://qs1969.pair.com?node_id=11140604


in reply to Get most recent data based on a date from an array of hashes.

I work with GMT time zone dates with the YYYY-MM-DD HH:MM:SS format often. String compare with this is fine. The key is that the leading zeroes are absolutely necessary. This is actually what a date looks like in an SQLite DB.

I see many fine posts with sorting techniques if @$data is large.

Not considered yet is what happens if more than one thing happened on the "most recent date"? In my data sets, measured to the second, I would allow for this possibility (and it very likely could indeed happen). Code below shows just one way.

#!/usr/bin/perl -w use strict; use Data::Dumper; use Data::Dump qw(dump dd); my $data = [ { 'Color' => 'green', 'Step' => 'Platform', 'acc' => '1111', 'Date' => '08-06-2022' }, { 'Color' => 'black', 'Step' => 'Platform', 'acc' => '1111', 'Date' => '01-05-2019' }, { 'Color' => 'reddish', 'Step' => 'Platform', 'acc' => '1111', 'Date' => '03-21-2021' }, { 'Color' => 'blue', 'Step' => 'Platform', 'acc' => '1111', 'Date' => '10-11-2020' }, { 'Color' => 'white', 'Step' => 'Platform', 'acc' => '1111', 'Date' => '08-06-2022' }, { 'Color' => 'red', 'Step' => 'Platform', 'acc' => '1111', 'Date' => '03-21-2021' }, ]; @$data = sort{my $A = $a->{Date}; my $B = $b->{Date}; $A =~ s/(\d+)-(\d+)-(\d+)/$3-$1-$2/; $B =~ s/(\d+)-(\d+)-(\d+)/$3-$1-$2/; $B cmp $A}@$data; my $most_recent_href = $data->[0]; dd $most_recent_href; #see if there are others on same date as most recent?? foreach my $href (@$data[1..@$data-1]) { if ($href->{Date} eq $most_recent_href->{Date}) { dd $href; } else {last;} } __END__ { acc => 1111, Color => "green", Date => "08-06-2022", Step => "Platfo +rm" } { acc => 1111, Color => "white", Date => "08-06-2022", Step => "Platfo +rm" }

Replies are listed 'Best First'.
Re^2: Get most recent data based on a date from an array of hashes.
by tybalt89 (Monsignor) on Jan 19, 2022 at 16:38 UTC

    Note that max_by() can also return multiple max's if it is used in list context.

    #!/usr/bin/perl use strict; use warnings; use List::AllUtils qw( max_by ); my $data = [ { acc => 1111, Color => "green", Date => "08-06-2022", Step => "Plat +form" }, { acc => 1111, Color => "black", Date => "01-05-2019", Step => "Plat +form" }, { acc => 1111, Color => "reddish", Date => "03-21-2021", Step => "Pl +atform" }, { acc => 1111, Color => "blue", Date => "10-11-2020", Step => "Platf +orm" }, { acc => 1111, Color => "white", Date => "08-06-2022", Step => "Plat +form" }, { acc => 1111, Color => "red", Date => "03-21-2021", Step => "Platfo +rm" }, ]; my @mostrecent = max_by {join '', (split /-/, $_->{Date})[2,0,1] } @$d +ata; use Data::Dump 'dd'; dd @mostrecent;

    Outputs:

    ( { acc => 1111, Color => "green", Date => "08-06-2022", Step => "Plat +form" }, { acc => 1111, Color => "white", Date => "08-06-2022", Step => "Plat +form" }, )
      This is way ++cool.
      I wasn't aware of List::AllUtils or List::Utilsby in the List:: menagerie

      List::Utils
      List::MoreUtils
      List::AllUtils
      List::SomeUtils
      List::UtilsBy