如何比较哈希数组中的元素并仅保留最新的项目



我正在使用下面的哈希数组,如果四个特定参数相同,我只想显示基于"日期时间"的最新哈希。让我使用以下代码提供一个示例...

如果"玩具,种类,舞台,步骤"是相同的,那么我只想将该哈希值存储到新的哈希数组中。

原始哈希数组

$VAR1 = [
      {
        'Color' => 'green',
        '2nd Color' => 'blue',
        '3rd Color' => 'yellow',
        'toy' => 'truck',
        'toy_type' => 'ford',
        'kind' => '4door',
        'Stage' => 'Production',
        'Step' => 'Platform',
        'Datetime' => '2012/06/08 01:49:19'
      },
      {
        'Color' => 'red',
        '2nd Color' => 'green',
        '3rd Color' => 'yellow',
        'toy' => 'truck',
        'toy_type' => 'ford',
        'kind' => '4door',
        'Stage' => 'Production',
        'Step' => 'Platform',
        'Datetime' => '2012/06/08 01:46:17'
      },
      {
        'Color' => 'red',
        '2nd Color' => 'blue',
        '3rd Color' => 'green',
        'toy' => 'truck',
        'toy_type' => 'chevy',
        'kind' => '4door',
        'Stage' => 'Production',
        'Step' => 'Platform',
        'Datetime' => '2012/06/08 01:52:14'
      },
      {
        'Color' => 'red',
        '2nd Color' => 'blue',
        '3rd Color' => 'yellow',
        'toy' => 'truck',
        'toy_type' => 'chevy',
        'kind' => '4door',
        'Stage' => 'Production',
        'Step' => 'Platform',
        'Datetime' => '2012/06/08 01:24:14'
      },
      {
        'Color' => 'white',
        '2nd Color' => 'blue',
        '3rd Color' => 'yellow',
        'toy' => 'truck',
        'toy_type' => 'gmc',
        'kind' => '4door',
        'Stage' => 'Production',
        'Step' => 'Platform',
        'Datetime' => '2012/06/08 06:24:14'
      },

我想保存到变量的新哈希数组:

$VAR2 = [
      {
        'Color' => 'green',
        '2nd Color' => 'blue',
        '3rd Color' => 'yellow',
        'toy' => 'truck',
        'toy_type' => 'ford',
        'kind' => '4door',
        'Stage' => 'Production',
        'Step' => 'Platform',
        'Datetime' => '2012/06/08 01:49:19'
      },
      {
        'Color' => 'red',
        '2nd Color' => 'blue',
        '3rd Color' => 'green',
        'toy' => 'truck',
        'toy_type' => 'chevy',
        'kind' => '4door',
        'Stage' => 'Production',
        'Step' => 'Platform',
        'Datetime' => '2012/06/08 01:52:14'
      },
      {
        'Color' => 'white',
        '2nd Color' => 'blue',
        '3rd Color' => 'yellow',
        'toy' => 'truck',
        'toy_type' => 'gmc',
        'kind' => '4door',
        'Stage' => 'Production',
        'Step' => 'Platform',
        'Datetime' => '2012/06/08 06:24:14'
      },

请注意,我只希望存储最新的福特和最近的雪佛兰,但由于只有一个GMC,我也希望存储它。

我指的是perldsc(http://perldoc.perl.org/perldsc.html)文档,但它没有涉及如此详细的内容。这可能吗?

sub key { join ':', @{ $_[0] }{qw( toy kind Stage Step )} }
# Determine which records to keep.
my %latest;
for my $rec (@$recs) {
    my $key = key($rec);
    $latest{$key} = $rec->{Datetime}
       if !$latest{$key} || $latest{$key} lt $rec->{Datetime};
}        
# Filter out the others.
@$recs = grep { $latest{key($_)}{Datetime} eq $_->{Datetime} } @$recs;

上述方法保留了原始顺序。它还优雅地处理领带(两者兼而有之)。

如果您不需要保留原始订单,则可以使用更简单的顺序。不幸的是,在平局的情况下,它只保留一条记录,并且其性能无法扩展 [O(N log N) 而不是 O(N)]。

sub key { join ':', @{ $_[0] }{qw( toy kind Stage Step )} }
my %seen;
@$recs =
   grep !$seen{key($_)}++,
    sort { $b->{Datetime} cmp $a->{Datetime} }
     @$recs;

(如果您希望按升序Datetime对最终结果进行排序,请在grep前面添加一个reverse

您是否考虑过改用哈希哈希? 然后,您可以使用车辆的品牌作为外部哈希中的键,并且任何先前的条目都会被自动覆盖,因此您最终只会得到每个品牌的最新条目。

您的数据似乎不是很有代表性,首先是因为所有记录中的关键字段toykindStageStep都是相同的,还因为数据没有像你所说的那样排序(至少它没有像我希望你的意思那样按日期/时间排序)。

此代码将返回数据中最早的唯一记录的列表。给定您的数据,它只返回第四条记录,因为它的日期2012/06/08 01:24:14比其他所有记录都早。

my %seen;
my @filtered = grep {
  not $seen{join '|', @$_{qw/ toy kind Stage Step /} }++
}
sort {
  $a->{Datetime} cmp $b->{Datetime}
} @data;

相关内容

最新更新