【问题标题】:Do I need to reset a Perl hash index?我需要重置 Perl 哈希索引吗?
【发布时间】:2014-03-12 14:17:43
【问题描述】:

好的,这是一个 N00b 问题,但它让我很难过:

我有以下 Perl 代码:

%project_keys = (
  cd     => "continuous_delivery",
  cm     => "customer_management",
  dem    => "demand",
  dis    => "dis",
  do     => "devops",
  sel    => "selection",
  seo    => "seo"
);

print "proj_code is $proj_code\n";
while ( ($key, $value) = each %project_keys ) {
    if ($key == $proj_code) {
        $url = "http://projects/".$project_keys{$key}."/setter";
        last;
    }
}

$proj_code 总是以相同的('dis') 传递,打印行显示了这一点。

但是,每次运行时,project_keys{$key} 都会得到不同的值。

我做错了什么(毫无疑问是显而易见的)?我看过 cmets 关于每个人是如何“脆弱”的——是这样吗?

【问题讨论】:

  • 为什么不说:$url = "http://projects/$project_keys{'dis'}" if exists $project_keys{'dis'};
  • 另外,你应该对字符串使用eq,而不是==。见perlop

标签: perl hash


【解决方案1】:

如果您已经拥有您所期望的“密钥”,请检查它是否存在并使用它...

另外,请始终使用use strict; use warnings;

#!/usr/bin/perl

use strict;
use warnings;

my $proj_code= 'dis';
my $url;

my %project_keys = (
  cd     => "continuous_delivery",
  cm     => "customer_management",
  dem    => "demand",
  dis    => "dis",
  do     => "devops",
  sel    => "selection",
  seo    => "seo"
);

$url = "http://projects/$project_keys{$proj_code}/setter" 
    if exists $project_keys{$proj_code};

print "url: $url\n";

输出:

url: http://projects/dis/setter

【讨论】:

  • 首先,谢谢。其次,将哈希键连接成正则表达式的最简单方法是什么 - 我想做这样的事情:if ($title =~ /(cd|cm|dem|dis|do|sel|seo)(\d+)\s.*/) { 然后在我的示例中检查 $1 而不是 proj_code 。基本上,如果这篇评论的标题是例如"cm1234 - do some DIS work",那么我需要把它链接到http://projects/customer_management/setter。那有意义吗?哈希表最终将来自一个文件,所以我根本不想要任何硬编码......
  • @roryhewitt np。你应该问另一个关于正则表达式键的问题。比结合两个单独的问题要好。
【解决方案2】:

是的,如果您使用 each 遍历哈希,但在没有返回任何结果之前一直迭代,您将在下一次中断的地方继续。

您可以在循环之前使用键或值将内部迭代器重置为开头,如下所示:

keys(%project_keys);
while ( ($key, $value) = each %project_keys ) {

也就是说,您还有许多其他问题:

使用eq,而不是==,来测试字符串是否相等。

你的整个循环毫无意义;您不需要需要遍历哈希来查找值;循环可以简单地替换为:

if ( exists $project_keys{$proj_code} ) {
    $url = "http://projects/$project_keys{$proj_code}";
}

【讨论】:

  • @ysyth,尽管您的答案不是“公认的答案”,但我很欣赏有关在 while 循环之前使用键的附加信息。
  • Perldoc confirms this:每个散列...都有自己的内部迭代器,由each访问...当each如前所述到达末尾时,迭代器被隐式重置;它可以通过在哈希上调用 keys ... 来显式重置。
【解决方案3】:

您正在使用each。最好不要。它很微妙,将状态存储在哈希中。

远胜于

while( my ( $key, $value ) = each %hash ) {
   ...
}

是在keys函数上使用foreach循环

foreach my $key ( keys %hash ) {
   my $value = $hash{$key};
   ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多