作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我必须处理根据月份日期变化的数据。当我从文件名中提取日期时,我得到了一个随机排列的日期,如下所示。
31 02 28 30 27 01 29 03 04
这是在处理从 8 月 27 日到 9 月 4 日的数据。我需要从 27 日到 4 日按顺序排列的日期。我必须一次处理 9 个日期。这个问题出现在月底,当时我有这个月的日期(大数字)和下个月的日期(小数字)。所以我对数组进行排序,我称之为@fdaylist。我明白了
01 02 03 04 27 28 29 30 31.
为了得到我想要的下面的脚本片段,完成工作并给出
27 28 29 30 31 01 02 03 04
我确定这个脚本是否可以一直运行。它多次重现序列,所以我必须使用 uniq() 函数。如果我能得到有关实现目标的更好方法的建议,我将不胜感激。
my $last_occ=lastidx { /0\d/ } @fdaylist;
if($last_occ > 1){
foreach(@fdaylist){
for(my $mm=$last_occ+1; $mm < @fdaylist; ++$mm){
push (@fday, $fdaylist[$mm]);
}
for(my $nn=0; $nn <= $last_occ; ++$nn){
push (@fday, $fdaylist[$nn]);
}
}
}
@fday = uniq(@fday);
最佳答案
我假设数字必须是连续的,有一个间隔,否则无法确定某些人属于哪一种方式。我还假设总是存在间隙。†(不。虽然日期确实是连续的,但它们可能跨越两个月或在一个月内,正如所澄清的那样。)
一种方法:遍历排序数组,从前到后移动项目,直到到达间隙
use warnings;
use strict;
use feature 'say';
# Dates are consecutive, either straddling two months or within a month
my @dates = (31, 02, 28, 30, 27, 01, 29, 03, 04); # or can be 05..13 etc
@dates = sort { $a <=> $b } @dates;
if (consec_nums(\@dates)) {
say "Consecutive numbers (dates in same month), nothing to do (@dates)";
}
else {
my $last_moved;
while (1) {
push @dates, $last_moved = shift @dates;
last if $dates[0] > $last_moved+1;
}
@dates = map { sprintf "%02d", $_ } @dates; # for 01 02 etc
}
say "@dates";
# Returns true (1) if numbers are consecutive, like consecutive dates
# in a single month, false (undef) otherwise. Assumes a sorted array
sub consec_nums {
my ($ra) = @_;
my $prev = $ra->[0];
for my $i (1..$#$ra) {
return if $ra->[$i] > $prev+1;
$prev = $ra->[$i];
}
return 1;
}
另一种方法:遍历已排序的数组以找到间隙之前的最后一个索引(之后数字不再连续);然后拼接推送
# same sorted @dates, same assumptions. same consec_nums() sub
if (consec_nums(\@dates)) {
say "Consecutive numbers (dates in same month), nothing to do (@dates)";
}
else {
my $consec_idx;
for my $i (0 .. $#dates) {
$consec_idx = $i, last
if $dates[$i]+1 < $dates[$i+1];
}
push @dates, splice @dates, 0, $consec_idx+1;
}
say "@dates";
† 对于上述假设:
如果我们可以得到 1 2 10 30 31
那么应该是 10 30 31 1 2
还是 30 31 1 2 10
?
如果没有间隙(一个月内的所有日期),如 05 .. 13
,则上述过程将中断。如果可能出现这种情况,那么首先对其进行测试。
已经在评论中澄清了这确实是可能的,所有日期都在一个月内。上面的答案已经通过针对这种情况的测试进行了修改。
关于perl - 当月的日期跨越当月末到下月初时,如何重新排列月的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68959716/
我是一名优秀的程序员,十分优秀!