我有一个数组,我使用natatime
中的List::MoreUtils
函数一次从中获取7个元素。它们都是0到62之间的正整数,没有特定的顺序,是随机的。
my @attn_range = (0, 39, 21, 17, 62, 43, 62,
1, 40, 22, 16, 60, 41, 59,
2, 41, 23, 15, 58, 39, 56,
3, 42, 24, 14, 56, 37, 53,
4, 43, 25, 13, 54, 35, 50,
5, 44, 26, 12, 52, 33, 47,
6, 45, 27, 11, 50, 31, 44,
7, 46, 28, 10, 48, 29, 41,
....
62, 23, 33, 45, 62, 39, 59);
our $it = List::MoreUtils::natatime(7, @attn_range);
while (1) {
while (my @vals = $it->()){
for my $i (0 .. $#vals){
print "Port$i: $vals[$i], ";
}
print "\n";
}
但是,我希望在达到列表末尾时从顶部循环回来,但是这种方法不会这样做。
你能帮帮我吗?我希望在我的while (1)
循环中读取并打印最后7个时回到顶部。
(在我的例子中,我在上面创建了一个数组@attn_range
,但实际上我的数组中的值是从.csv文件中读取的,而@attn_range数组非常大且是7的倍数。使用natatime
,因为我发现它很简单,可以采用任何方式从我的数组中取出7个元素。)
答案 0 :(得分:4)
没有办法重置" natatime
返回的迭代器:每次执行外部while
时,您只需创建一个新的迭代器
除非你有充分的理由这样做,否则不要使用our
这段代码应该可以运行,但要注意它会无限循环运行,因为外部while
没有退出
while () {
my $iter = List::MoreUtils::natatime(7, @attn_range);
while ( my @vals = $iter->() ) {
for my $i ( 0 .. $#vals ) {
printf "Port%d: %d, ", $i, $vals[$i];
...
}
}
print "\n";
}
现在我回到合适的键盘上,我可以提供一些我希望更有用的东西
一遍又一遍地创建一个七元素迭代器是浪费的,我宁愿将数据复制到一个七元素数组的数组中
此代码显示了这个想法,并且还使用join
和map
来生成您在问题中描述的输出。每个七项目块在for
循环中可用@$group
,其元素为$group->[0]
到$group->[6]
use strict;
use warnings 'all';
use feature 'say';
my @attn_range = (
0, 39, 21, 17, 62, 43, 62,
1, 40, 22, 16, 60, 41, 59,
2, 41, 23, 15, 58, 39, 56,
3, 42, 24, 14, 56, 37, 53,
4, 43, 25, 13, 54, 35, 50,
5, 44, 26, 12, 52, 33, 47,
6, 45, 27, 11, 50, 31, 44,
7, 46, 28, 10, 48, 29, 41,
62, 23, 33, 45, 62, 39, 59,
);
my @groups;
{
for ( my $i = 0; $i < @attn_range; $i += 7 ) {
push @groups, [ @attn_range[ $i .. $i+6 ] ];
}
}
while () {
for my $group ( @groups ) {
say join ', ', map {
sprintf 'Port%d: %2d', $_, $group->[$_];
} 0 .. $#$group;
}
exit; # For testing
}
答案 1 :(得分:1)
与前面答案中的解决方案不同,以下解决方案不要求@attn_range
具有7个元素的倍数:
sub make_cyclic_natatime {
my ($n, @list) = @_;
die if !@list;
my $i = -1;
return sub {
return map { $list[++$i % @list] } 1..$n;
};
}
my $iter = make_cyclic_natatime(7, @attn_range);
while (1) {
my @vals = $iter->();
say join ', ', map { "Port$i: $vals[$i]" } 0..$#vals;
select(undef, undef, undef, 0.100);
}
或者只是
die if !@attn_range;
my $i = -1;
while (1) {
my @vals = map { $attn_range[++$i % @attn_range] } 1..7;
say join ', ', map { "Port$i: $vals[$i]" } 0..$#vals;
select(undef, undef, undef, 0.100);
}
缺点是这些解决方案不会像早期答案的第二个解决方案那么快。