1

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

如果 'toy, kind, Stage, Step' 相同,那么我只想将该哈希存储到一个新的哈希数组中。

原始哈希数组

$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) 文档,但它没有详细介绍。这甚至可能吗?

4

3 回答 3

3
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;

(如果您希望最终结果按升序排序,请reverse在前面添加。)grepDatetime

于 2012-06-11T19:39:27.670 回答
0

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

于 2012-06-11T19:18:32.793 回答
0

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

此代码将返回数据中最早的唯一记录的列表。鉴于您的数据,它只返回第四条记录,因为它的日期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;
于 2012-06-11T21:49:33.467 回答