• Perl学习笔记(3)----遍历哈希表的一个容易疏忽的地方


      今天做 Google的 Code Jam 上的一道题目:https://code.google.com/codejam/contest/351101/dashboard#s=p2,用Perl语言解答的。遇到一个关于hash遍历的问题,思考了好一会儿才发现问题所在,为了简化叙述,写了一个简单的遍历哈希表的Perl程序如下:

      

      

      1 #!/usr/bin/perl
      2 my %hash=(
      3         1=>"a",
      4         2=>"b",
      5         3=>"c",
      6         4=>"d",
      7         5=>"e",
      8         6=>"f",
      9         7=>"g",
     10         8=>"h",
     11         9=>"i",
     12         0=>"j",
     13 );
     14 for(keys %hash){
     15         print "$_ => $hash{$_}
    ";
     16 }
     17 my $times;
     18 for(my $i=1;$i<=4;$i++){
     19         $times=0;
     20         print "====================Loop No.$i:=====================
    ";
     21 LOOP1:  while(my ($key,$value)=each %hash){
     22                 $times++;
     23                 print "	'$key'=>'$value'
    ";
     24                 if ($times>=2){
     25                         last LOOP1;
     26                 }
     27         }
     28 }

    该程序 2 ~ 13 行先建立了一个哈希表,然后遍历输出这个哈希表。

    接下来的 18 ~ 28 行,用 while 循环和哈希表的 each 函数遍历该哈希表,用 for 循环控制遍历四次,每次遍历只遍历两个哈希表中的值。按照设想,这四次的遍历应当输出同样的内容,但输出如下:

    6 => f
    3 => c
    7 => g
    9 => i
    2 => b
    8 => h
    1 => a
    4 => d
    0 => j
    5 => e
    ====================Loop No.1:=====================
        '6'=>'f'
        '3'=>'c'
    ====================Loop No.2:=====================
        '7'=>'g'
        '9'=>'i'
    ====================Loop No.3:=====================
        '2'=>'b'
        '8'=>'h'
    ====================Loop No.4:=====================
        '1'=>'a'
        '4'=>'d'

    由结果可以看出,这四次的输出并非都是一样的,这说明,用 while 循环 + each 函数遍历哈希表的时候,如果提前跳出了while循环,那么下次再接着用 each 函数遍历该哈希表的时候,会从上次已经遍历过的关键字的下一个关键字处开始遍历。

    如果将 while 循环改成 for 或 foreach 循环呢?(Perl 中 for 和 foreach 其实是等价的):

      1 #!/usr/bin/perl
      2  my %hash=(
      3          1=>"a",
      4          2=>"b",
      5          3=>"c",
      6          4=>"d",
      7          5=>"e",
      8          6=>"f",
      9          7=>"g",
     10          8=>"h",
     11          9=>"i",
     12          0=>"j",
     13  );
     14  for(keys %hash){
     15          print "$_ => $hash{$_}
    ";
     16  }
     17 my $times;
     18 for(my $i=1;$i<=4;$i++){
     19         $times=0;
     20         print "========== Loop No.$i ==========
    ";
     21         foreach(my ($key,$value)=each %hash){
     22                 $times++;
     23                 print "	'$key'=>'$value' 	and times=$times
    ";
     24         }
     25 }

    输出结果如下:

    6 => f
    3 => c
    7 => g
    9 => i
    2 => b
    8 => h
    1 => a
    4 => d
    0 => j
    5 => e
    ========== Loop No.1 ==========
        '6'=>'f'     and times=1
        '6'=>'f'     and times=2
    ========== Loop No.2 ==========
        '3'=>'c'     and times=1
        '3'=>'c'     and times=2
    ========== Loop No.3 ==========
        '7'=>'g'     and times=1
        '7'=>'g'     and times=2
    ========== Loop No.4 ==========
        '9'=>'i'     and times=1
        '9'=>'i'     and times=2

    每次 foreach 循环会遍历两次,而且并没有改变循环的关键字,有点奇怪啊...

  • 相关阅读:
    [Flex] IFrame系列 —— 嵌入本地页面两种方式source和content(html页面和html代码)
    [Flex] IFrame系列 —— 在flex的web应用中嵌入html的方法
    [Other] 自定义MIME类型支持FLV的相关设置
    [AIR] 利用SnapShot.exe实现QQ截屏功能
    [ActionScript 3.0] 跨域策略文件crossdomain.xml配置详解
    [ActionScript 3.0] 通过三角形获得 3D 效果
    [Java] 实现一个基于命令行的用户管理
    [Java] 将标准字符流写入到文件中(通过控制台写一个html程序,并保存)
    [Java] 使用转换流来处理标准输入
    MySQL索引介绍
  • 原文地址:https://www.cnblogs.com/dongling/p/5705224.html
Copyright © 2020-2023  润新知