Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Perl中如何将块(键和值)从散列中移出?_Perl - Fatal编程技术网

在Perl中如何将块(键和值)从散列中移出?

在Perl中如何将块(键和值)从散列中移出?,perl,Perl,我有以下部分代码: while(my $path = shift(@paths)) { # Do stuff } 在循环中,我向@path添加了另一个键,因此在下一次迭代中它将处理该路径 我不得不将@path的结构从数组更改为散列。如何替换while循环?由此,我尝试: while(my $path = shift(@{[keys(%paths)]})) 但问题是它将执行无限循环,因为移位在匿名数组上工作,而不是在%路径上工作。此外,我还需要记住更新循环中的%路径的情况: my $p

我有以下部分代码:

while(my $path = shift(@paths)) {
    # Do stuff
}
在循环中,我向
@path
添加了另一个键,因此在下一次迭代中它将处理该路径

我不得不将
@path
的结构从数组更改为散列。如何替换while循环?由此,我尝试:

while(my $path = shift(@{[keys(%paths)]}))
但问题是它将执行无限循环,因为移位在匿名数组上工作,而不是在
%路径上工作。此外,我还需要记住更新循环中的
%路径的情况:

my $p = "/some/path";
$paths{$p} = "open";

因此,在循环的下一个迭代中,它也将处理此路径。我也不能使用
foreach
,因为我更新了
%路径。这里最好的解决方案是什么?

检索密钥,然后
删除哈希项

while (my ($key) = keys %paths) {       # NB: list context assignment
    my $value = delete $paths{$key};
    ...
}

检索密钥,然后
删除
散列项

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可能会产生一些奇怪的效果。

您可以执行与以前相同的操作,但使用不同的队列:

my @queue = keys %path;

while( my $key = shift @queue ) {
    $path{$new_key} = ...;
    push @queue, $new_key;
    }

我通常对更改我正在迭代的数据结构感到紧张。Perl可能会产生一些奇怪的效果。

另一种可能是使用带有手动循环控制的裸块:

使用严格;
使用警告;
我的%hash=(
foo=>1,
bar=>2,
baz=>3,
);
散列:{
我的($key)=密钥%hash;
my$value=删除$hash{$key};
打印“$key=>$value\n”;
#有时会将新值添加到哈希中。
#
如果($key eq'foo'){
$hash{qux}=42;
}
如果%HASH;
};

我觉得裸块循环使用不足。

另一种可能是使用带手动循环控制的裸块:

使用严格;
使用警告;
我的%hash=(
foo=>1,
bar=>2,
baz=>3,
);
散列:{
我的($key)=密钥%hash;
my$value=删除$hash{$key};
打印“$key=>$value\n”;
#有时会将新值添加到哈希中。
#
如果($key eq'foo'){
$hash{qux}=42;
}
如果%HASH;
};

我觉得裸块循环没有得到充分利用。

切换到哈希是个错误。使用路径值对数组

my@todo=([“/some/path”,“open”]);
while(@todo){
my($path,$value)=@{shift(@todo)};
...
推@todo,[…,…];
...
}

切换到哈希是错误的。使用路径值对数组

my@todo=([“/some/path”,“open”]);
while(@todo){
my($path,$value)=@{shift(@todo)};
...
推@todo,[…,…];
...
}

如果
“0”
可以是散列键,您还需要测试
定义的($key)
或只测试
,而(key%路径){my($key)=key%路径;删除$path{$key};..}
或将键放入一个数组中并从该数组转换过来……请注意,对于较长的列表,mob和choroba的方法将非常缓慢。有效的方法:
while(keys%路径){my($key,$val)=每个%path;keys%路径;删除$path{$key};..}
。丑得要命。有关更好的方法,请参见我的答案。@TLP,那么您必须保持哈希和列表同步。有一种更好的方法。如果
“0”
可以是散列键,您还需要测试
定义的($key)
或只测试
while(keys%路径){my($key)=keys%路径;删除$path{$key};…}
或者只是将键放入一个数组中,然后从中切换……请注意,对于较长的列表,mob和choroba的方法将非常缓慢。有效的方法:
while(keys%路径){my($key,$val)=每个%path;keys%路径;删除$path{$key};..}
。丑得要命。有关更好的方法,请参见我的答案。@TLP,那么您必须保持哈希和列表同步。有一个更好的方法。无论你想做什么,这几乎肯定是个坏主意。您应该描述您正试图通过这种奇怪的解决方案解决的问题。OP正在处理一个列表,处理过程可以向列表中添加新元素。“添加另一个键…以便在下一次迭代中它将处理该路径”-一旦切换到哈希,新的密钥必须在下一次迭代中处理吗?这几乎肯定是个坏主意,不管你想做什么。你应该描述你试图用这个奇怪的解决方案解决什么问题。OP正在处理一个列表,处理过程可以向列表中添加新元素。“添加另一个键……这样在下一次迭代中它将处理该路径”——一旦你切换到哈希,新键必须在下一次迭代中处理吗?