我不断学习哈希和你可以做的各种事情。 我有这个问题。当我有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;
答案 0 :(得分:3)
<强> 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
),请使用太空船操作符<=>
而不是字符串比较运算符cmp
。有关详细信息和示例,请参阅perldoc -f sort
。)
编辑:您尚未说明日期的格式。如果它们采用YYYY-MM-DD
格式,则按上述排序方式可行,但如果它们位于{{1例如,MM-DD-YYYY
格式会出现在01-01-2014
之前。处理此问题的最简单方法是将日期的组成部分从最重要到最不重要(即年份跟随月份,然后是日期)重新排序。您可以使用Time::Piece这样执行此操作:
12-01-2013
另一个小问题:一般来说,你应该只在你使用之前声明变量。除了降低可读性之外,通过在程序顶部声明所有内容,你什么都得不到。
答案 1 :(得分:0)
您可以将key1和key2连接成一个键,如下所示:
$key = "$key1 key2";
$pick{$key} = $value;