使用natatime时无法回送

时间:2016-08-25 22:58:20

标签: perl

我有一个数组,我使用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个元素。)

2 个答案:

答案 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";
}


更新

现在我回到合适的键盘上,我可以提供一些我希望更有用的东西

一遍又一遍地创建一个七元素迭代器是浪费的,我宁愿将数据复制到一个七元素数组的数组中

此代码显示了这个想法,并且还使用joinmap来生成您在问题中描述的输出。每个七项目块在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);
}

缺点是这些解决方案不会像早期答案的第二个解决方案那么快。