如何使数组无限循环?
How to make an array loop indefinitely?
我有一个名单:
@names = qw(John Peter Michael);
我想从中获取 2 个值,所以我得到了 John 和 Peter。如果我想再拿 2 个 - 我会得到迈克尔和约翰。还有 1 个 - 彼得。还有 3 个 - Michael John 和 Peter,等等。
我已经开始编写一个子程序,其中将设置并记住全局索引 ID,并且一旦达到数组的标量限制就会将其自身重置为零,但后来我在某处读到 Perl 数组 "remember" 他们被循环的位置。
这是真的还是我误会了什么?有什么方法可以轻松完成我的任务吗?
推出自己的迭代器并不难,但perlfaq4
满足您的需求:
How do I handle circular lists?
(contributed by brian d foy)
If you want to cycle through an array endlessly, you can increment the
index modulo the number of elements in the array:
my @array = qw( a b c );
my $i = 0;
while( 1 ) {
print $array[ $i++ % @array ], "\n";
last if $i > 20;
}
You can also use Tie::Cycle
to use a scalar that always has the next element of the circular array:
use Tie::Cycle;
tie my $cycle, 'Tie::Cycle', [ qw( FFFFFF 000000 FFFF00 ) ];
print $cycle; # FFFFFF
print $cycle; # 000000
print $cycle; # FFFF00
The Array::Iterator::Circular
creates an iterator object for circular arrays:
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
我从来没有完全理解那个机制(它只在 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";
输出:
约翰·彼得
迈克尔、约翰、彼得、迈克尔
我有一个名单:
@names = qw(John Peter Michael);
我想从中获取 2 个值,所以我得到了 John 和 Peter。如果我想再拿 2 个 - 我会得到迈克尔和约翰。还有 1 个 - 彼得。还有 3 个 - Michael John 和 Peter,等等。
我已经开始编写一个子程序,其中将设置并记住全局索引 ID,并且一旦达到数组的标量限制就会将其自身重置为零,但后来我在某处读到 Perl 数组 "remember" 他们被循环的位置。
这是真的还是我误会了什么?有什么方法可以轻松完成我的任务吗?
推出自己的迭代器并不难,但perlfaq4
满足您的需求:
How do I handle circular lists?
(contributed by brian d foy)
If you want to cycle through an array endlessly, you can increment the index modulo the number of elements in the array:
my @array = qw( a b c ); my $i = 0; while( 1 ) { print $array[ $i++ % @array ], "\n"; last if $i > 20; }
You can also use
Tie::Cycle
to use a scalar that always has the next element of the circular array:use Tie::Cycle; tie my $cycle, 'Tie::Cycle', [ qw( FFFFFF 000000 FFFF00 ) ]; print $cycle; # FFFFFF print $cycle; # 000000 print $cycle; # FFFF00
The
Array::Iterator::Circular
creates an iterator object for circular arrays: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
我从来没有完全理解那个机制(它只在 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";
输出:
约翰·彼得
迈克尔、约翰、彼得、迈克尔