如何在 Perl 中从散列中移动块(键和值)?
How to shift block (key and value) from hash in Perl?
我有以下部分代码:
while(my $path = shift(@paths)) {
# Do stuff
}
在循环内部有一种情况,我将另一个键添加到 @paths
因此在下一次迭代中它将处理该路径。
我不得不将 @paths
的结构从数组更改为散列。如何替换 while 循环?从这个,我试过:
while(my $path = shift(@{[keys(%paths)]}))
但问题是它将进行无限循环,因为移位适用于匿名数组而不适用于 %paths
。另外我需要记住我在循环内更新 %paths
的情况:
my $p = "/some/path";
$paths{$p} = "open";
因此在循环的下一次迭代中它也将处理这条路径。我也无法使用 foreach
,因为我更新了 %paths
。这里最好的解决方案是什么?
检索密钥,然后delete
哈希条目
while (my ($key) = keys %paths) { # NB: list context assignment
my $value = delete $paths{$key};
...
}
您可以执行与之前相同的操作,但使用不同的队列:
my @queue = keys %path;
while( my $key = shift @queue ) {
$path{$new_key} = ...;
push @queue, $new_key;
}
我通常对更改正在迭代的数据结构感到紧张。 Perl 在那里可能会产生一些奇怪的效果。
另一种可能性是使用带有手动循环控制的裸块:
use strict;
use warnings;
my %hash = (
foo => 1,
bar => 2,
baz => 3,
);
HASH: {
my ($key) = keys %hash;
my $value = delete $hash{$key};
print "$key => $value\n";
# Sometimes new values will be added to the hash.
#
if ( $key eq 'foo' ) {
$hash{quux} = 42;
}
redo HASH if %hash;
};
我觉得裸块循环没有得到充分利用。
切换到哈希是一个错误。使用一组路径值对。
my @todo = ( [ "/some/path", "open" ] );
while (@todo) {
my ($path, $value) = @{ shift(@todo) };
...
push @todo, [ ..., ... ];
...
}
我有以下部分代码:
while(my $path = shift(@paths)) {
# Do stuff
}
在循环内部有一种情况,我将另一个键添加到 @paths
因此在下一次迭代中它将处理该路径。
我不得不将 @paths
的结构从数组更改为散列。如何替换 while 循环?从这个
while(my $path = shift(@{[keys(%paths)]}))
但问题是它将进行无限循环,因为移位适用于匿名数组而不适用于 %paths
。另外我需要记住我在循环内更新 %paths
的情况:
my $p = "/some/path";
$paths{$p} = "open";
因此在循环的下一次迭代中它也将处理这条路径。我也无法使用 foreach
,因为我更新了 %paths
。这里最好的解决方案是什么?
检索密钥,然后delete
哈希条目
while (my ($key) = keys %paths) { # NB: list context assignment
my $value = delete $paths{$key};
...
}
您可以执行与之前相同的操作,但使用不同的队列:
my @queue = keys %path;
while( my $key = shift @queue ) {
$path{$new_key} = ...;
push @queue, $new_key;
}
我通常对更改正在迭代的数据结构感到紧张。 Perl 在那里可能会产生一些奇怪的效果。
另一种可能性是使用带有手动循环控制的裸块:
use strict;
use warnings;
my %hash = (
foo => 1,
bar => 2,
baz => 3,
);
HASH: {
my ($key) = keys %hash;
my $value = delete $hash{$key};
print "$key => $value\n";
# Sometimes new values will be added to the hash.
#
if ( $key eq 'foo' ) {
$hash{quux} = 42;
}
redo HASH if %hash;
};
我觉得裸块循环没有得到充分利用。
切换到哈希是一个错误。使用一组路径值对。
my @todo = ( [ "/some/path", "open" ] );
while (@todo) {
my ($path, $value) = @{ shift(@todo) };
...
push @todo, [ ..., ... ];
...
}