【问题标题】:How to make an array loop indefinitely?如何使数组无限循环?
【发布时间】:2018-06-23 18:22:22
【问题描述】:

我有一个名字列表:

@names = qw(John Peter Michael);

我想从中获取 2 个值,所以我得到了 John 和 Peter。如果我想再拿两个 - 我得到迈克尔和约翰。还有 1 个 - 彼得。还有 3 个 - Michael John 和 Peter,等等。

我已经开始编写一个子例程,其中将设置和记住全局索引 ID,并且一旦达到数组的标量限制就会将自身重置为零,但后来我在某处读到 Perl 数组“记住”它们的位置被循环了。

这是真的还是我误解了什么?有没有一种方法可以轻松完成我的任务?

【问题讨论】:

    标签: arrays perl loops infinite-loop


    【解决方案1】:

    推出您自己的迭代器并不难,但perlfaq4 满足您的需求:


    如何处理循环列表?

    (由布赖恩·d·福伊提供)

    如果你想无休止地循环遍历一个数组,你可以递增 索引以数组中元素的数量为模:

    my @array = qw( a b c );
    my $i = 0;
    while( 1 ) {
        print $array[ $i++ % @array ], "\n";
        last if $i > 20;
    } 
    

    您还可以使用Tie::Cycle 来使用始终具有循环数组的下一个元素的标量:

    use Tie::Cycle;
    tie my $cycle, 'Tie::Cycle', [ qw( FFFFFF 000000 FFFF00 ) ];
    print $cycle; # FFFFFF
    print $cycle; # 000000
    print $cycle; # FFFF00
    

    Array::Iterator::Circular 为循环数组创建一个迭代器对象:

    use Array::Iterator::Circular;
    my $color_iterator = Array::Iterator::Circular->new(
        qw(red green blue orange)
        );
    foreach ( 1 .. 20 ) {
        print $color_iterator->next, "\n";
    }
    

    自己动手制作的品种

    子程序真的很简单(在下面的代码中实现为circularize)。 $i 的值保留在$colors 的作用域内,所以不需要状态变量:

    sub circularize {
      my @array = @_;
      my $i = 0;
      return sub { $array[ $i++ % @array ] }
    }
    
    my $colors = circularize( qw( red blue orange purple ) ); # Initialize
    
    print $colors->(), "\n" for 1 .. 14; # Use
    

    【讨论】:

    • 我确实喜欢自己滚动的方法,尽管它需要稍作调整才能满足获取 N 个元素的原始规范。我想过做一些类似的事情,但状态刚刚从我的脑海中弹出到页面上。非常好。
    【解决方案2】:

    我从来没有完全理解过这种机制(它只在 foreach 上吗?)。我只会使用状态值,例如:

    my @names = qw(John Peter Michael);
    
    sub GetNames($) {
      my $count = shift;
      my @result = ();
    
      state $index = 0;
      state $length = scalar(@names);
    
      while($count--) {
        push(@result, $names[($index++ % $length)]);
      }
      return @result;
    }
    
    
    print join(", ", GetNames(2)), "\n\n";
    print join(", ", GetNames(4)), "\n";
    

    输出:

    约翰,彼得

    迈克尔,约翰,彼得,迈克尔

    【讨论】:

    • 查看我的回答,了解如何在不依赖 state 变量的情况下做到这一点
    • 需要use feature 'state';(或use v5.10;)。 @Zaid,我喜欢你的回答 (+1),但至于 state 功能——它在概念上比闭包更简单。
    • 每个人都有自己的:)
    • 评论。依赖全局@names 限制了它的使用。 $length 不必是state,也不需要scalar,只需my $len = @names;。我没有看到在这里使用原型的好处(示例中没有使用它)。
    • True true...不是一个非常有用的sn-p代码。 @Zaid 的代码绝对更适合重用。
    猜你喜欢
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    相关资源
    最近更新 更多