我正在使用下面的哈希数组,如果四个特定参数相同,我只想显示基于"日期时间"的最新哈希。让我使用以下代码提供一个示例...
如果"玩具,种类,舞台,步骤"是相同的,那么我只想将该哈希值存储到新的哈希数组中。
原始哈希数组
$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
。
您是否考虑过改用哈希哈希? 然后,您可以使用车辆的品牌作为外部哈希中的键,并且任何先前的条目都会被自动覆盖,因此您最终只会得到每个品牌的最新条目。
您的数据似乎不是很有代表性,首先是因为所有记录中的关键字段toy
、kind
、Stage
和Step
都是相同的,还因为数据没有像你所说的那样排序(至少它没有像我希望你的意思那样按日期/时间排序)。
此代码将返回数据中最早的唯一记录的列表。给定您的数据,它只返回第四条记录,因为它的日期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;