joh*_*lak 13 arrays variables perl foreach loops
是否可以在Perl foreach循环中为数组中的两个变量分配相同的数据?
我使用Perl 5,我想我在Perl 6中遇到了一些东西.
像这样的东西:
my $var1;
my $var2;
foreach $var1,$var2 (@array){...}
Run Code Online (Sandbox Code Playgroud)
Dav*_*man 14
它不是Perl 5核心语言,但是List :: Util有一个pairs
应该足够接近的函数(以及许多其他pair...
函数可能更方便,具体取决于你在循环中做的事情):
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use List::Util 'pairs';
my @list = qw(a 1 b 2 c 3);
for my $pair (pairs @list) {
my ($first, $second) = @$pair;
say "$first => $second";
}
Run Code Online (Sandbox Code Playgroud)
输出:
a => 1
b => 2
c => 3
Run Code Online (Sandbox Code Playgroud)
最简单的方法是使用一个while
循环,splice
每次调用数组的前两个元素,
while (my($var1, $var2) = splice(@array, 0, 2)) {
...
}
Run Code Online (Sandbox Code Playgroud)
然而,与之不同的是foreach
,这在原始数组上不断进行双重移位,所以当你完成时,数组是空的.此外,分配的变量是副本,而不是别名foreach
.
如果您不喜欢,可以使用C风格的for
循环:
for (my $i = 0; $i < @array; $i += 2) {
my($var1, $var2) = @array[$i, $i+1];
...
}
Run Code Online (Sandbox Code Playgroud)
这使得数组保持不变,但不允许您按照方式更新它foreach
.为此,您需要直接处理数组.
my @pairlist = (
fee => 1,
fie => 2,
foe => 3,
fum => 4,
);
for (my $i = 0; $i < @pairlist; $i += 2) {
$pairlist[ $i + 0 ] x= 2;
$pairlist[ $i + 1 ] *= 2;
}
print "Array is @pairlist\n";
Run Code Online (Sandbox Code Playgroud)
打印出:
Array is feefee 2 fiefie 4 foefoe 6 fumfum 8
Run Code Online (Sandbox Code Playgroud)
如果你努力尝试,你可以把它们变成别名变量,但它可能不值得:
my @kvlist = (
fee => 1,
fie => 2,
foe => 3,
fum => 4,
);
for (my $i = 0; $i < @kvlist; $i += 2) {
our ($key, $value);
local(*key, $value) = \@kvlist[ $i, $i + 1 ];
$key x= 2;
$value *= 2;
}
print "Array is @kvlist\n";
Run Code Online (Sandbox Code Playgroud)
打印出预期更改的数组:
Array is feefee 2 fiefie 4 foefoe 6 fumfum 8
Run Code Online (Sandbox Code Playgroud)
请注意,由所提供的对表::成对模块,这不过是非常最近添加到核心列表::的Util模块(所以你可能无法使用),仍然没有给你的别名:
use List::Util 1.29 qw(pairs);
my @pairlist = (
fee => 1,
fie => 2,
foe => 3,
fum => 4,
);
for my $pref (pairs(@pairlist)) {
$pref->[0] x= 2;
$pref->[1] *= 2;
}
print "Array is @pairlist\n";
Run Code Online (Sandbox Code Playgroud)
仅打印出来:
Array is fee 1 fie 2 foe 3 fum 4
Run Code Online (Sandbox Code Playgroud)
所以它根本没有改变阵列.哎呀.:(
当然,如果这是一个真正的哈希值,你可以简单地将值加倍:
for my $value (values %hash) { $value *= 2 }
Run Code Online (Sandbox Code Playgroud)
有效的原因是因为它们是实际哈希值的别名.
您无法更改密钥,因为它们是不可变的.但是,您可以轻松地创建一个新哈希,它是旧版本的更新副本:
my %old_hash = (
fee => 1,
fie => 2,
foe => 3,
fum => 4,
);
my %new_hash;
@new_hash{ map { $_ x 2 } keys %old_hash } =
map { $_ * 2 } values %old_hash;
print "Old hash is: ", join(" " => %old_hash), "\n";
print "New hash is: ", join(" " => %new_hash), "\n";
Run Code Online (Sandbox Code Playgroud)
那输出
Old hash is: foe 3 fee 1 fum 4 fie 2
New hash is: foefoe 6 fiefie 4 fumfum 8 feefee 2
Run Code Online (Sandbox Code Playgroud)