簡體   English   中英

按值排序2鍵哈希值

[英]sort 2 key hash by value

我不斷學習哈希和你可以做的各種事情。 我有這個問題。 當我有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;

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格式,如上所述排序將起作用,但如果它們是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");

另一個小問題:一般來說,你應該只在你使用它們之前聲明變量。 除了降低可讀性之外,通過在程序頂部聲明所有內容,您無法獲得任何好處。

您可以將key1和key2連接成一個鍵,如下所示:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM