Найти дату прошлой пятницы в Perl 6? - PullRequest
0 голосов
/ 09 мая 2018

Я хочу сгенерировать последовательность, которая заканчивается в прошлую пятницу с понедельника по четверг и в пятницу предыдущей недели, если последовательность начинается в субботу и воскресенье.То есть, если предположить, что сегодня 2018-05-09, то в прошлую пятницу 2018-05-04. Если сегодня 2018-05-12, то в прошлую пятницу также 2018-05-04.Поэтому я пишу:

(Date.today, *.earlier(:1day) ... ( *.day-of-week==5 && *.week[1]+1==Date.today.week[1] )).tail # Output: 2018-05-06

Но результат равен 2018-05-06 вместо 2018-05-04.

Тогда я использовал Junction :

(Date.today, *.earlier(:1day) ... all( *.day-of-week==5,  *.week[1]+1==Date.today.week[1] )).tail # Output: 2018-05-04

Почему && в первой ситуации не так?Оператор ... говорит, что:

Правая часть будет иметь конечную точку, которая может быть Inf или * для «бесконечных» списков (элементы которых создаются толькопо требованию), выражение, которое завершает последовательность, когда оно истинно, или другие элементы, такие как соединения.

Что не так с оператором &&?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Проблема в вашем конечном состоянии

*.day-of-week==5 && *.week[1]+1==Date.today.week[1]

Это две лямбда-выражения Wh независимоCode, каждый из которых принимает 1 аргумент.

*.day-of-week==5
*.week[1]+1==Date.today.week[1]

Поскольку объект кода является истинным значением, оператор && переходит ко второму. Таким образом, последовательность останавливается, когда она достигает воскресенья предыдущей недели.

Даже если бы код представлял собой одну лямбду, он не работал бы так, как вы ожидаете, поскольку это была бы лямбда, которая принимает два аргумента.

Правильный способ сделать эту проверку - использовать какой-то блок.

{.day-of-week==5 && .week-number+1 == Date.today.week-number}

Это может быть хорошей идеей, чтобы обернуть это в подпрограмму, чтобы вы могли проверить это.

sub last-friday ( Date:D $date ) {
  # cache it so that it doesn't have to be looked up on each iteration
  my $week-number = $date.week-number - 1;

  (
    $date,
    *.earlier( :1day )

    ...

    {
          .day-of-week == 5
      &&
          .week-number == $week-number
    }
  ).tail
}

say last-friday Date.new: :year(2018), :month( 5), :day( 9); # 2018-05-04
say last-friday Date.new: :year(2018), :month( 5), :day(12); # 2018-05-04

say Date.today.&last-friday; # 2018-05-04

Вы также можете просто рассчитать правильную дату.

sub last-friday ( Date:D $date ) {
  $date.earlier:
    days => (
      $date.day-of-week # reset to previous sunday
      + 2               # go two days earlier to get friday
    )
}

say last-friday Date.new: :year(2018), :month( 5), :day( 9); # 2018-05-04
say last-friday Date.new: :year(2018), :month( 5), :day(12); # 2018-05-04

say Date.today.&last-friday; # 2018-05-04
0 голосов
/ 09 мая 2018

Эта последовательность будет идти с сегодняшнего дня до последней пятницы:

say Date.today, *.earlier(:1day) ...  *.day-of-week==5
# OUTPUT: «(2018-05-09 2018-05-08 2018-05-07 2018-05-06 2018-05-05 2018-05-04)␤» 

Также

say Date.new("2018-05-11"), *.earlier(:1day) ...  *.day-of-week==5;
# OUTPUT: «(2018-05-11)␤»

Последний аргумент оператора ... - это терминатор последовательности или условие, которому он должен соответствовать. Если последовательность должна закончиться в пятницу, самое простое условие - то, что выше.

...