【问题标题】:sort 2 key hash by value按值对 2 个键散列进行排序
【发布时间】:2023-03-25 19:27:01
【问题描述】:

我一直在学习哈希和你可以用它们做的各种事情。 今天我有这个问题。当我有 2 个键时,如何按值对哈希进行排序?以及如何打印出来? 我有一个 csv 文件。我试图将值存储在哈希中,按值排序。这样我就可以打印最大和最小值,我还需要这个值在那里的日期。 到目前为止,我可以打印哈希,但我无法对其进行排序。

#!/usr/bin/perl 
#find openMin and openMax. 
use warnings; 
use strict;

my %pick;
my $key1;
my $key2;
my $value;  
my  $file= 'msft2.csv';              
my $lines = 0;
my $date;
my $mm;
my $mOld = "";

my $open;
my $openMin;
my $openMax;
open (my $fh,'<', $file) or die "Couldnt open the $file:$!\n";
while  (my $line=<$fh>)
{ 
    my @columns = split(',',$line);
    $date = $columns[0];
    $open = $columns[1];

    $mm = substr ($date,5,2);

    if ($lines>=1) {                        #first line of file are names of columns     wich i 
    $key1 = $date;                         #dont need. data itself begins with second line 
    $key2 = "open";
    $value = $open;
    $pick{$key1}{"open"}=$value; 


   }
 $lines++;
} 
foreach $key1 (sort keys %pick) {
foreach $key2 (keys %{$pick{$key1}}) {
    $value = $pick{$key1}{$key2};
    print "$key1 $key2 $value \n";

 }
}
exit;

【问题讨论】:

    标签: perl sorting hash key-value


    【解决方案1】:

    1.使用真正的 CSV 解析器

    使用 split /,/ 解析 CSV 可以正常工作...除非您的某个字段包含逗号。如果您绝对、肯定、100% 确定您的代码将永远不必在其中一个字段中解析带有逗号的 CSV,请随意忽略这一点。如果没有,我建议使用Text::CSV。示例用法:

    use Text::CSV;
    
    my $csv = Text::CSV->new( { binary => 1 } )
        or die "Cannot use CSV: " . Text::CSV->error_diag ();
    
    open my $fh, "<", $file or die "Failed to open $file: $!";
    while (my $line = $csv->getline($fh)) {
        print @$line, "\n";
    }
    $csv->eof or $csv->error_diag();
    close $fh;
    

    2。排序

    我在您的哈希中只看到一个辅助键:open。如果您尝试根据 open 的值进行排序,请执行以下操作:

    my %hash = (
        foo => { open => "date1" },
        bar => { open => "date2" },
    );
    
    foreach my $key ( sort { $hash{$a}{open} cmp $hash{$b}{open} } keys %hash ) {
        print "$key $hash{$key}{open}\n";
    }
    

    (假设您要排序的值不是数字。如果值是数字(例如3-17.57),请使用宇宙飞船运算符&lt;=&gt; 而不是字符串比较运算符cmp。请参阅perldoc -f sort 了解详细信息和示例。)

    编辑:您还没有解释日期的格式。如果它们是YYYY-MM-DD 格式,则按上述排序将起作用,但如果它们是MM-DD-YYYY 格式,例如,01-01-2014 将出现在 12-01-2013 之前。解决此问题的最简单方法是将日期的组成部分从最重要到最不重要重新排序(即年,月,日)。您可以像这样使用Time::Piece 执行此操作:

    use Time::Piece;
    
    my $date = "09-26-2013";
    my $t = Time::Piece->strptime($date, "%m-%d-%Y");
    print $t->strftime("%Y-%m-%d");
    

    另一个花絮:一般来说,您应该只在使用变量之前声明它们。通过在程序顶部声明所有内容,除了降低可读性之外,您一无所获。

    【讨论】:

      【解决方案2】:

      您可以将 key1 和 key2 连接成一个键:

      $key = "$key1 key2";
      $pick{$key} = $value;
      

      【讨论】:

      • 它可能是一个选项。但是为了学习缘故,我想知道如何用 2 个键按值对哈希进行排序。
      • 没有“排序哈希”或“排序两键哈希”。它总是基于一些比较函数“排序列表”。
      猜你喜欢
      • 1970-01-01
      • 2012-10-09
      • 2014-05-07
      • 1970-01-01
      • 2014-01-08
      • 1970-01-01
      • 2010-10-19
      • 2018-03-03
      • 2014-07-03
      相关资源
      最近更新 更多