4

我有以下数组引用数组:

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 标准数组 - (Year, Month, Day)

4

4 回答 4

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!!";
    }
}
于 2012-06-12T21:18:34.193 回答
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);
}
于 2012-06-12T21:17:58.860 回答
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";
    }
}
于 2012-06-12T21:17:59.840 回答
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)=@$holiday; #Capturing year month and day from the array reference
    my ($d_y,$d_m,$d_d)=@$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
于 2012-06-12T21:23:25.450 回答