2012-06-12 57 views
4

我引用下面的數組的數組:匹配陣列的值引用數組中 - Perl的

my @holidays = [[2012,'01','02'],[2012,'01','16'],[2012,'02','20'],[2012,'04','16'],[2012,'05','28'],[2012,'07','04'],[2012,'09','03'],[2012,'10','08'],[2012,'11','12'],[2012,'11','22'],[2012,'12','25']]; 

哪些是IRS在2012年公認的法定節假日,我想數組匹配@dueDate到該數組中的一個值,並返回1,如果存在則返回true。

while ($holidays[@dueDate]){ 
     print ("Found Holiday \t join('-',@dueDate)"); 
     @dueDate = Add_Delta_Days(@dueDate, 1); 
     if (Day_of_Week(@dueDate) > 5){ 
      @dueDate = Monday_of_Week((Week_Number(@dueDate)+1), $dueDate[0]); 
     } 
    } 

是我目前的嘗試 - while語句的條件從來都不是真的。我已經嘗試了幾種不同的引用和解引用假期的組合,但無濟於事。

在while語句中操作評估的最好方法是什麼,以便當@dueDate在上面的數組中包含日期時執行該塊。

注:@dueDate爲Date :: Calc的標準陣列 - (年,月,日)

+0

多少元素不@dueDate包含哪些內容? –

+0

@dueDate包含3個元素 - 四位數年,兩位數月份和兩位數日。 – voteblake

+0

這是兩個變量是如何在while語句的調用顯示在Eclipse調試器: 的dueDate \t ... \t \t [0] \t [1] \t [2] \t @holidays \t \t ... \t [0] \t ARRAY(0x3567c78)... \t \t \t [0] \t ARRAY(0x356a4f0)... \t \t \t \t [0] \t \t \t \t [1] \t \t \t \t [2] \t \t \t [1] \t ARRAY(0x379d4f0)... \t \t \t [2] \t ARRAY(0x356b898)... \t \t \t [3] \t ARRAY(0x3567948)... \t \t \t [4] \t ARRAY(0x2a846d8)... \t \t \t [5] \t ARRAY(0x356bf88)... \t \t \t [6] \t ARRAY(0x2a84738)... \t \t \t [7] \t ARRAY(0x356bda8)... \t \t \t [8] \t ARRAY(0x356b880)... \t \t \t [9] \t陣列(0x356b8c8)... \t \t \t [10] \t陣列(0x356bd60)... – voteblake

回答

3

這應該讓你走上正軌。我在代碼中看到兩個問題 - 一個數組數組在外部應該有正常的圓括號,並使用~~運算符來比較數組是否相等。

my @holidays = ([2012,'01','02'],[2012,'01','16'],[2012,'02','20'],[2012,'04','16'], 
[2012,'05','28'],[2012,'07','04'],[2012,'09','03'],[2012,'10','08'],[2012,'11','12'], 
[2012,'11','22'],[2012,'12','25']); 
my $i; 
my @duedate = [2012, '01', '02']; 

for ($i = 0; $i < @holidays; $i++) 
{ 
    if (@holidays[$i] ~~ @duedate) 
    { 
     print "matched!!"; 
    } 
} 
+1

用於@fxzuz for循環。感謝您的幫助 - 我知道我的數組語法錯了。 – voteblake

+1

哼,我看到你接受了這個解決方案。請記住它相當低效。它必須檢查每個@holiday的比賽。這是O(N)操作。我的是O(1)。無論您有多少假期,只需一張支票即可查看日期是否爲假期。 – ikegami

2

首先,

my @holidays = [[2012,'01','02'],...,[2012,'12','25']]; 

應該

my @holidays = ([2012,'01','02'],...,[2012,'12','25']); 

你創造一個單一元素的數組。


可能最好的方法來實現你想要的是使用散列。

my %holidays = map { join('-', @$_) => 1 } @holidays; 

然後,所有你需要的是

while ($holidays{join('-', @dueDate)}) { 
    my $dow = Day_of_Week(@dueDate); 
    @dueDate = Add_Delta_Days(@dueDate, 
     $dow == 5 || $dow == 6 ? 8 - $dow : 1); 
} 
2

這就是我的回答,工作Perl的5.14,也是我用smartmatching ~~運算符來比較兩個數組。

您分配給數組@holidays = [[2012,'01','02'],];是不正確的,你實際上給匿名數組[['2012','01','02']]分配給@holidays的第一個元素。

use v5.14; 

my @holidays = (['2012', '01', '02'], ['2012', '01', '16']); 
my @due_date = ('2012', '01', '16'); 

for my $holiday (@holidays) { 

    if (@$holiday ~~ @due_date) { 
     say "holiday match"; 
    } 
} 
0

好的,幾件事情:

1:列出包含在括號和文字數組引用在括號之間寫入。所以,你應該有:

my @holidays = ([2012,'01','02'],[2012,'01','16'],[2012,'02','20'],[2012,'04','16'],[2012,'05','28'], [2012,'07','04'],[2012,'09','03'],[2012,'10','08'],[2012,'11','12'],[2012,'11','22'],[2012,'12','25']);

2:當你看$holidays[@dueDate],你在標量上下文調用一切。特別是,因爲@dueDate有三個元素,所以只能看到$holidays[3]

3:除非你正在寫一塊一次性密碼,總是use strict;use warnings;

所以,你想是這樣的:

use strict; 
use warnings; 

my @holidays = ([2012,'01','02'],[2012,'01','16'],[2012,'02','20'],[2012,'04','16'],[2012,'05','28'], 
    [2012,'07','04'],[2012,'09','03'],[2012,'10','08'],[2012,'11','12'],[2012,'11','22'],[2012,'12','25']); 

my @dueDates=([2012,'01','01'],[2012,'01','02'],[2012,'01','03']); #Or whatever 

my @due_dates_that_are_holidays=(); 

foreach my $due_date(@dueDates) 
{ 
    foreach my $holiday(@holidays) 
    { 
    my ($h_y,$h_m,$h_d)[email protected]$holiday; #Capturing year month and day from the array reference 
    my ($d_y,$d_m,$d_d)[email protected]$due_date; #Ditto for the due date 

    if($h_y == $d_y and $h_m eq $d_m and $h_d eq $d_d) 
    { 
     push @due_dates_that_are_holidays,$due_date; 
    } 
    } 
} 
print join("-",@{$_}) . "\n" foreach(@due_dates_that_are_holidays); 

上面的代碼產生以下輸出:

2012-01-02 
+0

這是一個更大的程序片段 - 嚴格和警告都包括在內。 – voteblake

+0

@voteblake - 嘿。只要確定。 – 2012-06-12 21:28:05