1

以下のハッシュの配列を使用しており、4 つの特定のパラメーターが同じである場合、「日時」に基づいて最新のハッシュのみを表示したいと考えています。以下のコードを使用して例を挙げましょう...

「おもちゃ、種類、ステージ、ステップ」が同じ場合、そのハッシュのみを新しいハッシュ配列に格納したいと思います。

ハッシュの元の配列

$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'
      },

最新の ford と最近の chevy だけを保存したかったのですが、gmc が 1 つしかなかったため、それも保存したかったことに注意してください。

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;

上記の方法では、元の順序が保持されます。また、ネクタイをエレガントに処理します (両方を保持します)。

元の順序を維持する必要がない場合は、より単純なものを使用できます。残念ながら、引き分けの場合に保持されるレコードは 1 つだけであり、そのパフォーマンスはスケーリングされません [O(N) ではなく O(N log N)]。

sub key { join ':', @{ $_[0] }{qw( toy kind Stage Step )} }

my %seen;
@$recs =
   grep !$seen{key($_)}++,
    sort { $b->{Datetime} cmp $a->{Datetime} }
     @$recs;

(最終結果を昇順でソートする場合reverseは、の前に a を追加します。)grepDatetime

于 2012-06-11T19:39:27.670 に答える
0

データはあまり代表的ではないようです。まず、キーフィールド、、、toyおよびがすべてのレコードで同一kindであり、データがあなたの言うように並べ替えられていないためです(少なくとも日付/時刻で並べ替えられていないため)私はあなたが意味したことを願っています)。StageStep

このコードは、データ内の最も古い一意のレコードのリストを返します。データを指定すると2012/06/08 01:24:14、他のすべてのレコードよりも早い日付の4番目のレコードのみが返されます。

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 に答える
0

代わりにハッシュのハッシュを使用することを検討しましたか? 次に、車両のメーカーを外側のハッシュのキーとして使用すると、以前のエントリが自動的に上書きされるため、最終的に各メーカーの最新のエントリのみになります。

于 2012-06-11T19:18:32.793 に答える