2

我正在尝试按记录号顺序显示哈希数据(即按哈希键排序)。我已将记录存储在带有关联记录号的哈希中。

我在这里做错了什么?

这是一些显示问题的类似代码

#!/usr/bin/env perl
use strict;
use Time::HiRes;

my $rec = {};
my %Data;
my $recno = 1;

while ($recno <= 100) {
   $rec->{recno} = $recno;
   $rec->{dt} = qx/date/;

   $Data{ $rec->{recno} } = $rec;

   # Initialize
   Time::HiRes::sleep(0.2);
   $recno++;
   $rec = {};
}

my $count = keys %Data;
print "Found $count records\n";

foreach my $rec (sort { $Data{$a} <=> $Data{$b} } keys %Data) {
#foreach my $rec (sort { $Data{$a} cmp $Data{$b} } keys %Data) {
  print "   Rec No: --".$rec."--\n";
  print "     Date: ". $Data{$rec}{dt}."\n";
}

有时它会按顺序显示哈希,有时则不会。有点与它看起来的记录数量有关。

Found 100 records
   Rec No: --1--
     Date: Thu Feb 13 15:19:46 UTC 2020

   Rec No: --31--
     Date: Thu Feb 13 15:19:52 UTC 2020

   Rec No: --32--
     Date: Thu Feb 13 15:19:52 UTC 2020

   Rec No: --33--
     Date: Thu Feb 13 15:19:52 UTC 2020

   Rec No: --34--
     Date: Thu Feb 13 15:19:52 UTC 2020

   Rec No: --35--
     Date: Thu Feb 13 15:19:52 UTC 2020

   Rec No: --36--
     Date: Thu Feb 13 15:19:53 UTC 2020
4

3 回答 3

3

您正在比较值,但您需要比较键:

for my $rec (sort { $a <=> $b } keys %Data) {
于 2020-02-13T15:33:00.220 回答
1

请参阅@choroba 的答案,以解决您所说的问题。

但是为了不首先出现问题,请为任务选择最佳数据结构。在这种情况下,您需要一个数组,而不是一个 hash。我还使用了更具描述性的变量名称和小写标识符(参见 Conway (2005))。

#!/usr/bin/env perl
use warnings;
use strict;
use Time::HiRes;

my $delay = 0.2;
my $num_dates = 100;
my @dates;

for ( 0 .. ($num_dates - 1) ) {   
   chomp( my $date = `date` );
   push @dates, $date;
   Time::HiRes::sleep($delay);
}

for ( 0..$#dates ) {
    print join( "\t", $_, $dates[$_] ), "\n";
}

参考:

达米安康威。(2005) Perl 最佳实践:开发可维护代码的标准和样式。奥莱利媒体:http ://shop.oreilly.com/product/9780596001735.do

于 2020-02-13T15:44:59.737 回答
0

稍微更正的代码会产生预期的结果。

注意:date在 Windows 中需要选项/T,否则它会等待用户输入

use strict;
use warnings;
use feature 'say';

use Time::HiRes;

my $debug = 0;                  # debug flag

my %Data;
my($rec_id,$record);            # declared here for format
my $num_records = 100;          # define number of records

foreach my $recno (1..$num_records) {
    say "Record: $recno" if $debug;

    my $rec = {};

    $rec->{recno} = $recno;
    $rec->{dt} = qx/date \/T/;  # /T required for Windows 

    $Data{ $rec->{recno} } = $rec;

    # Initialize
    Time::HiRes::sleep(0.2);
    $recno++;
    $rec = {};
}

my $count = keys %Data;
say  "Total $count records";

$~ = 'STDOUT_HEAD';
write;
$~ = 'STDOUT';

foreach $rec_id (sort { $a <=> $b } keys %Data) {
    $record = $Data{$rec_id}{dt};
    write;
}

$~ = 'STDOUT_BOTTOM';
write;

format STDOUT_HEAD =
+------+------------------------------+
| No.  | Record                       |
+------+------------------------------+
.

format STDOUT =
| @>>> | @<<<<<<<<<<<<<<<<<<<<<<<<<<< |
$rec_id, $record
.

format STDOUT_BOTTOM =
+------+------------------------------+
.

输出

Total 100 records
+------+------------------------------+
| No.  | Record                       |
+------+------------------------------+
|    1 | Thu 02/13/2020               |
|    2 | Thu 02/13/2020               |
|    3 | Thu 02/13/2020               |
|    4 | Thu 02/13/2020               |
|    5 | Thu 02/13/2020               |
|    6 | Thu 02/13/2020               |
|    7 | Thu 02/13/2020               |
|    8 | Thu 02/13/2020               |
|    9 | Thu 02/13/2020               |
|   10 | Thu 02/13/2020               |
.......................................
.......................................
|   95 | Thu 02/13/2020               |
|   96 | Thu 02/13/2020               |
|   97 | Thu 02/13/2020               |
|   98 | Thu 02/13/2020               |
|   99 | Thu 02/13/2020               |
|  100 | Thu 02/13/2020               |
+------+------------------------------+
于 2020-02-13T19:38:23.737 回答