如何递增列表中的值?

How to increment through the values in a list?

我多次尝试搜索此问题,但无法形成与我的问题实际相关的搜索结果。
我正在尝试构建一个脚本来解析 SVG 文件(XML 生成图形内容的文本格式文件)以查找特定提示并分配 RGB 值。 (每个 RGB 值都会略有不同。)
为此,我描绘了多个递增变量(例如 $i、$j 和 $k),这些变量基于解析文本文件时发现的触发器递增。 但是,我需要增加的数量不是“1”。此外,所需的值是十六进制形式。 我可以设置一些东西,其中变量按给定的数量递增,例如 +33,但我还需要将数字转换为十六进制,弄清楚如何重新开始等。

我想到了一种更通用、更强大、更优雅的方法,但我不知道该怎么做。
如何设置这些递增变量以递增我在数组中设置的值?
例如,假设我的 RGB 潜在值是 @rgbval = (00,33,66,99,cc,ff)。
如何使 $i 从此列表中的一个值变为下一个值?
更好的是,我怎么能让 $i++ (或类似的东西)意味着“转到@rgbval 中的下一个元素的值”?
假设这是可能的,我如何告诉 Perl 在到达数组末尾后从元素 [0] 开始?

所以你有一个字符串,它是数字的十六进制表示

my $hex = 'cc';

要对其进行算术运算,您首先需要将其转换为数字。

my $num = hex($hex);

现在我们可以对其进行算术运算了。

$num += 33;

如果我们想把它转换回十六进制,我们可以使用

$hex = sprintf("%02x", $num);

$i通常用于索引。如果那是你想要的,你可以使用以下内容:

for my $i (0..$#rgbval) {
   # Do something with $i and/or $rgbval[$i]...
}

如果您希望 $i 接受每个值,您可以使用以下内容:

for my $i (@rgbval) {
   # Do something with $i...
}

但你似乎想要一个环绕的计数器。

直接的解决方案是使用 if 语句。

my $i = 0;
while (...) {
   # Do something with $i and/or $rgbval[$i]...

   ++$i;
   $i = 0 if $i == @rgbval;
}

但我会使用模运算。

my $i = 0;
while (...) {
   # Do something with $i and/or $rgbval[$i]...

   $i = ( $i + 1 ) % @rgbval;
}

或者,您可以旋转阵列。

while (...) {
   # Do something with $rgbval[0]...

    push @rgbval, shift(@rgbval);
}

Ikegami,您的回复包含了多么出色的信息。
我发现你的三个建议太吸引人了,无法忽视,并试图理解它们。您的第一部分是关于处理所描述的数学,转换为十六进制和从十六进制转换。
我试图将这些步骤与您对模数重置的建议一起纳入“概念测试”脚本。 (好吧,一个“概念理解测试”。)
对于测试脚本,我使用迭代器而不是搜索触发事件,这看起来更简单。
目标是让值递增到示例数组中列出的十六进制数字,并在最后一个值之后重新开始。 所以我迭代了十次,让价值观有机会重新开始。
在我发现我需要每次加 51 而不是 33 来获得这些示例值,并且还必须使我的数组的数值大 51 倍,因为我递增 51,它工作得很好嗯:

my $num = hex("00");
my @rgbval = qw(a b c d e f);
for my $i (0..10) {
   print ( "For i=$i, $num is " , sprintf("%02x ", $num) , "\n");
   $num = ( $num + 51 ) % ( 51 * @rgbval );
}

output:
~\Perlscripts>iterate2.pl
For i=0, $num is 00
For i=1, $num is 33
For i=2, $num is 66
For i=3, $num is 99
For i=4, $num is cc
For i=5, $num is ff
For i=6, $num is 00
For i=7, $num is 33
For i=8, $num is 66
For i=9, $num is 99
For i=10, $num is cc

就非数学方法而言,递增数组的字符串,我理解你是说我需要递增引用数组值的索引。我确实设法将自己与不同的迭代器以及它们在做什么混淆了,但是在几次失误之后,我也能够使这种方法起作用:

my @hue = qw(00 33 66 99 cc ff);
my $v = 0;
for my $i (0..10) {
   print "$i=$i, $hue[$v]=" , $hue[$v] , "\n";
   $v = ( $v + 1 ) % @hue;
}

output:
~\Perlscripts>iterate2.pl
$i=0, $hue[0]=00
$i=1, $hue[1]=33
$i=2, $hue[2]=66
$i=3, $hue[3]=99
$i=4, $hue[4]=cc
$i=5, $hue[5]=ff
$i=6, $hue[0]=00
$i=7, $hue[1]=33
$i=8, $hue[2]=66
$i=9, $hue[3]=99
$i=10, $hue[4]=cc

你最后提出的解决方案,用 push 和 shift 旋转数组似乎是最新颖的方法并且非常引人注目,特别是当我意识到如果我有一个存储移位值的变量,那将是正确的值下次推,一圈又一圈。 在这种方法中,我什至不必担心在最后一个值之后重新开始;不断变化的数组会自动为我处理:

my @hue = qw(00 33 66 99 cc ff); 
for my $i (0..10) {
   my $curval = shift(@hue);
   print "$i=$i, $curval is $curval               \.\.\.And the array is currently: ( @hue )\n";
   push(@hue,$curval);
}

output:
~\Perlscripts>iterate2.pl
$i=0, $curval is 00 ...And the array is currently: ( 33 66 99 cc ff )
$i=1, $curval is 33 ...And the array is currently: ( 66 99 cc ff 00 )
$i=2, $curval is 66 ...And the array is currently: ( 99 cc ff 00 33 )
$i=3, $curval is 99 ...And the array is currently: ( cc ff 00 33 66 )
$i=4, $curval is cc ...And the array is currently: ( ff 00 33 66 99 )
$i=5, $curval is ff ...And the array is currently: ( 00 33 66 99 cc )
$i=6, $curval is 00 ...And the array is currently: ( 33 66 99 cc ff )
$i=7, $curval is 33 ...And the array is currently: ( 66 99 cc ff 00 )
$i=8, $curval is 66 ...And the array is currently: ( 99 cc ff 00 33 )
$i=9, $curval is 99 ...And the array is currently: ( cc ff 00 33 66 )
$i=10, $curval is cc ...And the array is currently: ( ff 00 33 66 99 )

最具教育意义和帮助!非常感谢。