这是构建利用数组的Perl哈希的正确方法吗?
这是我第一次以这种方式操作哈希和数组——它正在工作。基本上,对于每个键,都有多个值,我希望记录这些值,然后以“键-->值-->值-->值…”的形式打印出来 我的代码如下。我很惊讶它能起作用,如此担心它“错误地”起作用。这是完成这项任务的正确方法,还是有更有效或更合适的方法这是构建利用数组的Perl哈希的正确方法吗?,perl,hash,arrays,Perl,Hash,Arrays,这是我第一次以这种方式操作哈希和数组——它正在工作。基本上,对于每个键,都有多个值,我希望记录这些值,然后以“键-->值-->值-->值…”的形式打印出来 我的代码如下。我很惊讶它能起作用,如此担心它“错误地”起作用。这是完成这项任务的正确方法,还是有更有效或更合适的方法 while ($source =~ m/(regex)/g) { #Get all key names from source $listkey = $1; #Set current list key to the c
while ($source =~ m/(regex)/g) { #Get all key names from source
$listkey = $1; #Set current list key to the current regex result.
$list{$listkey} = ++$i unless $list{$listkey}; #Add the key to the hash unless it already exists.
$list{$listkey} = [] unless exists $list{$listkey}; #Add an array for the hash unless the hash already exists.
while ($loopcount==0) {
if ($ifcount==0) {
$listvalue=result_of_some_function_using_list_key; #Get the first list value by using the list key.
$ifcount++; #Increment so we only get the first list value once.
} else {
$listvalue=result_of_some_function_using_list_value; #Update the list value by using the last list value.
}
if ($listvalue) { #If the function returned a value...
push @{$list{$listkey}}, $listvalue; #...then add the value to the hash array for the key.
} else { #There are no more values and we need a new key.
$listkey=0; #Reset variable.
$listvalue=0; #Reset variable.
$loopcount++; #Increment loop counter to exit loop.
}
}
$ifcount=0; #Reset count variable so the next listvalue can be generated from the new key.
$loopcount=0; #Reset count variable so another loop can begin for a new key.
}
foreach $listkey (keys %list) { #For each key in the hash.
print "$listkey --> "; #Print the key.
@values = @{$list{$listkey}}; #Reference the arrays of the hash.
print join ' --> ', @values; #Print the values.
print "\n"; #Print new line.
}
不!如果这样做有效,那肯定是“错误的”。但很明显,这不是您真正的代码,您在将其“翻译”到示例中时又添加了几个错误,因此很难准确判断意图是什么,但从程序的框架来看,它看起来应该是这样的:
my %result;
while ($source =~ m/(regex)/g) {
my $key = $1;
my $value = mangle($key);
while ($value) {
push @{ $results{$key} }, $value;
$value = frob($value);
}
}
再也没有了。您试图初始化哈希的操作没有达到您认为的效果(并且没有必要),您编写的while循环根本不是一个好主意,所有全局变量也都不是。上面的代码有许多不必要的步骤。Perl是一种非常有表现力的语言,允许这样的逻辑非常简单地表达:
# uncomment for some sample data
# sub function {"@_" !~ /^\[{3}/ and "[@_]"}
# my $source = 'one two three';
my %list;
while ($source =~ m/(\S+)/g) {
my $key = $1;
my $value = function($key);
while ($value) {
push @{ $list{$key} }, $value;
$value = function($value)
}
}
for my $key (keys %list) {
print join(' --> ' => $key, @{$list{$key}}), "\n";
}
下面的代码与您的代码相同,没有不必要的步骤
while ($source =~ m/(regex)/g) { # Get all key names from source
$listkey = $1; # Grab current regex result.
$listvalue = result_of_some_function_using_list_key;
while ($listvalue) {
push @{$list{$listkey}}, $listvalue;
$listvalue = result_of_some_function_using_list_value;
}
$listkey = 0; # Reset variable.
$domain = 0; # Reset variable.
}
然而,正如其他人所评论的,在大多数情况下应该避免使用全局变量。相反,列表键和列表值应在词汇上限定为my()
,用于生成列表值的函数应采用一个或多个参数(域、列表键和/或列表值)作为输入
台词
$list{$listkey} = ++$i unless $list{$listkey};
$list{$listkey} = [] unless exists $list{$listkey};
在不需要原始代码的情况下,使用
push@{$list{$key},$value
初始化条目就足够了;使用警告modeOuch,它生成了一个糟糕的警告列表。我将不得不仔细阅读它们。我希望真正的代码没有这么多注释。我很惊讶没有人向您指出数据结构食谱,即a.a.perldoc perldsc-许多示例。不,真正的代码没有这么多注释。:)谢谢你的食谱链接!谢谢,经过简短的解释,我对我的错误有了更好的理解。同意。一般来说,在Perl中,您应该只看到循环索引($i=0…C-style循环)或计数器,在实际需要对这些值进行处理的情况下。计数器和索引通常也是难以发现错误的一个很好的来源