hash类型

hash类型也称为字典、关联数组、映射(map)等等,其实它们都是同一种东西:键值对。每一个Key对应一个Value。

  • hash会将key/value散列后,按序放进hash桶。散列后的顺序和存放数据的顺序无关
  • hash类型的key只能是字符串,value可以是字符串、数值、undef或其它类型的标量
  • hash的key必须唯一,不能重复
  • perl中使用符号%表示hash类型,如%myhash。使用$hashname{index}访问hash中的元素
  • perl中可以单独对每一个hash元素赋值,也可以以列表的方式一次性赋多个值(初始化时可用)
  • 一次性赋值多个时,每个value跟在自己的key后面,用逗号分隔,每个key/value对之间也使用逗号分隔
    • 也就是说,它们的顺序是:{键1,值1,键2,值2...}
  • perl中可用使用"胖箭头"(=>)替代逗号,让整个hash看起来很清晰
  • 访问hash中不存在的元素,会返回undef
$phone_num{longshuai}="18012345678";
$phone_num{xiaofang}="17012345678";
$phone_num{fairy}="16012345678";

等价于以下几种方式:

%phone_num1=("longshuai","18012345678",   # 注意是括号,不是大括号
"xiaofang","17012345678",
"fairy","16012345678"); my %phone_num1=("longshuai" => "18012345678", # 将hash声明为局部hash
"xiaofang" => "17012345678",
"fairy" => "16012345678");
  • 使用胖箭头赋值的时候,如果key命名够规范(字母、数字、下划线),可以省略key部分的引号,perl会自动加上。在引用hash中的元素时,也一样可省略引号。如$phone_num{"longshuai"}$phone_num{longshuai}都有效
%phone_num1=(longshuai =>"18012345678",
xiaofang =>"17012345678",
fairy =>"16012345678");

如果key命名不够规范,则不会自动加上引号。有时候,这可能会当作一个表达式进行计算:

$myhash{foo.bar}    # $myhash{foobar}
  • 可以将hash赋值给另一个hash
%hash_name1 = %hash_name2;

Perl中的这个赋值过程和一般语言不太一样,它会先将%hash_name2展开成列表,然后再将这个列表赋值给新列表%hash_name1

  • 可以直接输出hash,如print %myhash,但不能加上引号,例如print "%myhash"不会输出hash里的元素
%myhash = (key1,value1,key2,value2,key3,value3);
print %myhash,"\n";
print "%myhash","\n";
  • perl中的ENV:perl可以通过ENV这个hash直接访问操作系统的环境变量
print $ENV{PATH};   # 输出操作系统的PATH环境变量

如果perl想访问操作系统中某个变量,可以直接在操作系统中设置,然后通过perl访问:

$ myvar=2;export myvar;

print $ENV{myvar};

hash相关函数

主要有reverse()、keys()、values()、exists()和delete()。

  • 可以用reverse函数反转hash。它会将hash当作列表一样反转,然后再将其当作hash。所以,原hash的key会变成后来的value,原value会变成后来的key
(key1,value1,key2,value2,key3,value3)

反转过程中:

(value3,key3,value2,key2,value1,key1)

反转后新的hash可能之一:

(value2,key2,value1,key1,value3,key3)

因为反转为新的hash时,是以原来的value当作新的key,所以可能会有重复的新key,perl采取的是覆盖生效:后存储的覆盖先存储的。

再者,反转为新的hash时,会对新的key重新hash计算存储到hash桶里,所以反转后的顺序不一定真的是反序的。这里的reverse更注重key/value的反转。

  • keys函数和values函数,分别返回key列表和value列表
  • keys函数和values函数在标量上下文中返回的是列表元素的个数
%myhash = (key1,value1,key2,value2,key3,value3);
@keys = keys %myhash;
@values = values %myhash;
$keys_num = keys %myhash;
print @keys,"\n";
print @values,"\n";
print $keys_num,"\n"; # 返回3

显然,key列表和value列表的顺序和存储的顺序可能是不一致的,但至少keys函数返回的列表中,如果key1排在最前,那么values函数返回的列表中,value1也肯定排在最前

  • 只要hash中包含任何一个键值对,在于布尔值判断上就返回真
if(%hash){
print "True\n";
}
  • exists()函数判断hash中是否存在某个key
  • delete()函数用于删除某个key/value,如果要删除的key/value不存在,则直接返回,不会报错

遍历hash

  • each可以遍历hash。each可以遍历数组和hash,它会获取索引和对应的值
  • each每次都获取一个键值对,并作上位置标记,以便下次从此开始继续遍历。换句话说,数组和hash有内部的迭代器
  • foreach也可以遍历hash,但它只能通过keys函数来遍历Key,间接遍历hash
%myhash = (key1,value1,key2,value2,key3,value3);

# each迭代遍历
while (($key,$value) = each %myhash){
print "$key: $value","\n";
} # foreach迭代遍历
foreach my $key (sort keys %myhash){
print $key,$myhash{$key},"\n";
}

需要注意的是each遍历,是不保证顺序的,foreach可以按照一定keys的顺序进行遍历。另外,在上面while each迭代的过程中,有几个过程:

  1. each %myhash首先迭代第一个键值对;
  2. 将获取到的第一个键值对赋值给($key,$value)
  3. 判断while的条件真假,因为赋值后得到的是一个包含键、值的列表,在while的标量上下文中,它返回列表中元素数量2,所以为真;
  4. 迭代到最后一个,each迭代不到key/value,所以列表元素数量为0,while的条件返回false,不会继续执行下去。

Perl中的hash类型的更多相关文章

  1. 6、Redis中对Hash类型的操作命令

    写在前面的话:读书破万卷,编码如有神 -------------------------------------------------------------------- ------------ ...

  2. python - hash类型操作

    Redis在内存中存储hash类型是以name对应一个字典形式存储的 常用操作 在name对应的hash中获取根据key获取valuehget(name,key) 在name 对应的hash 中设备键 ...

  3. Redis中Value使用hash类型的效率是普通String的两倍

    什么Redis? 点击这里 最近要开发的一个项目是分布式缓存组件,解决参数缓存高效获取的问题.参数达到了500万级别,刚刚开始了解Redis.做设计的时候考虑到Value使用哪种类型的问题? 主要面临 ...

  4. hash 在 perl 中的用法(转载)

    Perl的数据结构中最有趣的一个特性是哈希(hash),它使得在数据片段之间建立键-值(key-value)关联成为可能.虽然这些哈希要远远比普通系统中以数字索引的数组用途更广,但是往往也会使初学者不 ...

  5. redis中关于使用string类型还是hash类型

    前篇:最近在做一个将redis中大数据量进行合并缩减优化的工作,其中一项按月将数据进行合并.将一个月的数据放入一个key-value键值对中. 例:p2d20180901-3.p2d20180902- ...

  6. Python(Redis 中 String/List/Hash 类型数据操作)

    1.下载 redis 模块 pip install redis 2.redis 数据库两种连接方式 简单连接 decode_responses=True,写入和读取的键值对中的 value 为 str ...

  7. 在 Perl 中使用 Getopt::Long 模块来接收用户命令行参数

    我们在linux常常用到一个程序需要加入参数,现在了解一下 perl 中的有关控制参数的模块 Getopt::Long ,比直接使用 @ARGV 的数组强大多了.我想大家知道在 Linux 中有的参数 ...

  8. 【转载】Perl中的引用

    为什么使用引用? 在perl4中,hash表中的value字段只能是scalar,而不能是list,这对于有些情况是很不方便的,比如有下面的数据: Chicago, USAFrankfurt, Ger ...

  9. 在Perl中使用Getopt::Long模块来接收用户命令行参数

    我们在linux常常用到一个程序需要加入参数,现在了解一下perl中的有关控制参数的函数.getopt.在linux有的参数有二种形式.一种是–help,另一种是-h.也就是-和–的分别.–表示完整参 ...

随机推荐

  1. 学以致用三十四-----python2.0加载图片

    想用做一个静态图片为背景的页面.结果遇到了一些阻碍.其主要原因还是路径没有找对.网上也参考了不少方法,也许是因为版本不同,处理的方法也不同,因此按照网上的处理方式,也没有得到解决. 为此困惑了一天.结 ...

  2. pointer-events: none 的两个应用场景

    简介 pointer-events: none 真是个神奇的属性. 该属性有什么用?借用 CSS3 pointer-events:none 应用举例及扩展 的总结来说: pointer-events: ...

  3. pyspider爬取tourism management 所有文章的标题 作者 摘要 关键词等等所有你想要的信息

    #!/usr/bin/env python # -*- encoding: utf-8 -*- # vim: set et sw=4 ts=4 sts=4 ff=unix fenc=utf8: # C ...

  4. 汇总java生态圈常用技术框架、开源中间件,系统架构及经典案例等

    转自:http://www.51testing.com/html/83/n-3718883.html 有人认为编程是一门技术活,要有一定的天赋,非天资聪慧者不能及也.非也,这是近几年,对于技术这碗饭有 ...

  5. 基于SVG.js实现网页初始化线条描绘效果

    前端实现看到一个网页的效果很cool(参考https://tympanus.net/Development/SVGDrawingAnimation/index2.html),决定自己去实现以下这个效果 ...

  6. Linux编程之fork函数

    在Linux中,fork函数的功能就是在一个进程中创建一个新的进程,当前调用fork函数的进程就是产生的新进程的父进程,新进程在以下也称为子进程.在新进程生成之后就会在系统中开始执行. 函数原型:pi ...

  7. maven 本地仓库无法更新到最新版本的jar包

    maven 本地仓库无法更新到最新版本的jar包 描述:maven 本地仓库无法更新最新版的jar包导致项目一直报错 解决:去jar包版本所在目录,删除掉所有红框内文件,重新用ide导入

  8. C#常用工具类——Excel操作类(ZT)

    本文转载于: http://www.cnblogs.com/zfanlong1314/p/3916047.html /// 常用工具类——Excel操作类 /// <para> ----- ...

  9. 【mysql注入】mysql注入点的技巧整合利用

    [mysql注入]mysql注入点的技巧整合利用 本文转自:i春秋社区 前言: 渗透测试所遇的情况瞬息万变,以不变应万变无谓是经验与技巧的整合 简介: 如下 mysql注入点如果权限较高的话,再知道w ...

  10. JavaScript 基础排序的实现(二)

    继上一篇O(n^2)的排序算法后,这一篇主要记录O(n*logn)的排序算法 1.快排(快速排序) 这一算法的核心思想为,先随机选一个数作为标兵或者说是标记(这个数一般来说选择该无序数组的中间那个元素 ...