代码之家  ›  专栏  ›  技术社区  ›  Structure

这是构建使用数组的Perl哈希的正确方法吗?

  •  5
  • Structure  · 技术社区  · 16 年前

    这是我第一次用这种方式操作散列和数组——它正在工作。基本上,对于每个键,都有多个值需要记录,然后以“key-->value-->value-->val…”的形式打印出来。

    我的代码如下。我很惊讶它的工作,如此关注它的工作“错误”。这是完成这项任务的正确方式,还是有更有效或更合适的方法?

    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.
    }
    
    3 回复  |  直到 16 年前
        1
  •  2
  •   markusk Kiril Kirilov    16 年前

    以下代码与您的代码相同,没有不必要的步骤。

    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 初始化一个条目。

        2
  •  2
  •   Eric Strom    16 年前

    上面的代码有许多不必要的步骤。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";
    }
    
        3
  •  1
  •   hobbs    16 年前

    不!如果这奏效,那肯定是“错误的”。但很明显,这不是您真正的代码,您在将其“翻译”为示例时又添加了几个错误,因此很难准确判断其意图是什么,但从程序的框架来看,它看起来应该是:

    my %result;
    
    while ($source =~ m/(regex)/g) {
      my $key = $1;
      my $value = mangle($key);
      while ($value) {
        push @{ $results{$key} }, $value;
        $value = frob($value);
      }
    }
    

    再也没有了。初始化散列的尝试并没有像您认为的那样(也不是必需的),编写的while循环根本不是一个好主意,全局变量也都不是。