Learning Perl 学习笔记 Ch6 哈希
2019-04-09 本文已影响0人
sakam0to
- 用键访问哈希的元素:
$hash{$key}
,哈希元素因赋值而诞生
demo6-1
:
#!/usr/bin/perl
$key="hello";
$hash{$key}="world";
print "Hello, $hash{$key}!\n";
./demo6-1
Hello, world!
访问哈希表里不存在的元素会得到undef
- 哈希的键必须是字符串,值可以是任何标量
- 要访问整个哈希需用保留字符
%
, 哈希可以很容易的转换成{键,值,键,值……}这样的列表,这个过程叫做哈希松绑 :@list = %hash
demo6-2
:
#!/usr/bin/perl
$capital_of_country{"China"} = "Beijing";
$capital_of_country{"America"} = "Washington DC";
$capital_of_country{"Britain"} = "London";
$capital_of_country{"France"} = "Paris";
$capital_of_country{"Japan"} = "Tokyo";
$capital_of_country{"Korea"} = "Seoul";
@list_of_capitals = %capital_of_country;
print "@list_of_capitals\n";
./demo6-2
America Washington DC China Beijing Korea Seoul Britain London France Paris Japan Tokyo
./demo6-2
Korea Seoul America Washington DC China Beijing Britain London France Paris Japan Tokyo
./demo6-2
Japan Tokyo America Washington DC China Beijing France Paris Korea Seoul Britain London
- 注意到这里每次执行打印的顺序都不一样,这是因为哈希算法基于一个随机的因子来计算实际存储的位置,所以哈希松绑后的顺序并不固定,但是键值对的关系不会改变,即一个键的后面,必然是哈希表中它对应的值
- 同样也可以用相反的方式给哈希赋值 :
%hash = @list
(列表必须有偶数个元素,才能转成『键/值』对)
demo6-3
:
#!/usr/bin/perl
@list_of_capitals = qw /China Beijing America WashingtonD.C Britain London France Paris Japan Tokyo Korea Seoul/;
%capital_of_country = @list_of_capitals;
foreach $key (keys %capital_of_country){
print "Country:$key Capital:$capital_of_country{$key}\n";
}
- 这里删掉了Washington和DC间的空格,因为
qw
会把空格识别为列表元素的分隔符 - keys 函数返回哈希表的键列表
- print 里使用了哈希元素的内插,但是对整个哈希表的内插是不支持的
- 哈希表的键必须是唯一的,如果有重名的键值对,后者将覆盖前者
./demo6-3
Country:Japan Capital:Tokyo
Country:Korea Capital:Seoul
Country:China Capital:Beijing
Country:Britain Capital:London
Country:France Capital:Paris
Country:America Capital:WashingtonD.C
结合哈希松绑和哈希赋值,可以实现简便的哈希表键值互换
%key_to_value = reverse %value_to_key
-
哈希赋值的另一种方式是使用胖箭头
=>
,这样可以更清楚的表示哈希表中『键/值』对的关系:
demo6-4
:
#!/usr/bin/perl
%capital_of_country = (
China => "Beijing",
America => "WashingtonD.C",
Britain => "London",
France => "Paris",
Japan => "Tokyo",
Korea => "Seoul",
);
foreach $key (keys %capital_of_country){
print "Country:$key Capital:$capital_of_country{$key}\n";
}
./demo6-4
Country:France Capital:Paris
Country:Britain Capital:London
Country:Japan Capital:Tokyo
Country:China Capital:Beijing
Country:America Capital:WashingtonD.C
Country:Korea Capital:Seoul
- 注意第二行使用的是圆括号
(
,而不是花括号{
,使用花括号的场景是访问哈希表中的元素,而哈希表赋值使用的是和列表赋值一样的圆括号(考虑下哈希解绑应该更容易理解) - 哈希赋值的最后一行有一个额外的逗号,这是正确的语法
-
keys
函数返回哈希表的键列表,values
函数返回哈希表中的值列表,虽然返回的列表中元素顺序是不固定的,但是对应位置的元素是成对的。keys[3]的元素必定是values[3]的键
demo6-5
:
#!/usr/bin/perl
%capital_of_country = (
China => "Beijing",
America => "WashingtonD.C",
Britain => "London",
France => "Paris",
Japan => "Tokyo",
Korea => "Seoul",
);
$index = 0;
@countries = keys %capital_of_country;
@capitals = values %capital_of_country;
while($index < @countries){
print "$countries[$index]'s capital is $capitals[$index]\n";
$index += 1;
}
./demo6-5
America's capital is WashingtonD.C
Japan's capital is Tokyo
China's capital is Beijing
France's capital is Paris
Britain's capital is London
Korea's capital is Seoul
-
哈希的遍历可以用
each
函数或者foreach
循环结构
-
each
函数内置定位器,每次调用都以数组的形式返回哈希表中的一对"键/值":
($key, $value) = each %hash
*当each
函数遍历完哈希表后会返回空数组
*keys
函数和values
函数会重置这个定位器
demo6-6
:
#!/usr/bin/perl
%capital_of_country = (
China => "Beijing",
America => "WashingtonD.C",
Britain => "London",
France => "Paris",
Japan => "Tokyo",
Korea => "Seoul",
);
while(($key, $value) = each %capital_of_country){
print "$key\'s capital is $value\n";
}
./demo6-6
America's capital is WashingtonD.C
Korea's capital is Seoul
France's capital is Paris
China's capital is Beijing
Japan's capital is Tokyo
Britain's capital is London
-
foreach
循环结构遍历keys
函数返回的键列表
-
exists
函数判断一个键是否存在于哈希表中,并以布尔值返回,delete
函数则根据键删除哈希表中对应的元素
demo6-7
:
#!/usr/bin/perl
$key = "test";
if(exists $hash{$key}){
print "1: key exists: $hash{$key}\n";
}else{
print "1: key doesn't exist.\n";
}
$hash{$key} = "success";
if(exists $hash{$key}){
print "2: key exists: $hash{$key}\n";
}else{
print "2: key doesn't exist.\n";
}
$hash{$key} = undef;
if(exists $hash{$key}){
print "3: key exists: $hash{$key}\n";
}else{
print "3: key doesn't exist.\n";
}
delete $hash{$key};
if(exists $hash{$key}){
print "4: key exists: $hash{$key}\n";
}else{
print "4: key doesn't exist.\n";
}
./demo6-7
1: key doesn't exist.
2: key exists: success
3: key exists:
4: key doesn't exist.
将哈希中的值设置为undef并不同于删除,exists
依然会返回真
-
环境变量哈希
%ENV
返回系统环境变量信息:
demo6-8
:
#!/usr/bin/perl
while(($key, $value) = each %ENV){
print "$key:$value\n";
}
./demo6-8
PWD:/home/jingjie/workspace/LearningPerl/ch6
LC_PAPER:zh_CN.UTF-8
GTK_IM_MODULE:ibus
GJS_DEBUG_OUTPUT:stderr
GNOME_TERMINAL_SERVICE::1.67
TEXTDOMAINDIR:/usr/share/locale/
LESSCLOSE:/usr/bin/lesspipe %s %s
XDG_SESSION_TYPE:x11
JRE_HOME:/usr/local/java/jdk1.8.0_201/jre
GJS_DEBUG_TOPICS:JS ERROR;JS LOG
LC_NUMERIC:zh_CN.UTF-8
LC_MONETARY:zh_CN.UTF-8
GDMSESSION:ubuntu
LC_ADDRESS:zh_CN.UTF-8
XMODIFIERS:@im=ibus
VTE_VERSION:5202
XDG_CURRENT_DESKTOP:ubuntu:GNOME
WINDOWPATH:1
LC_NAME:zh_CN.UTF-8
_:./demo6-8
CLASSPATH:.:/usr/local/java/jdk1.8.0_201/lib:/usr/local/java/jdk1.8.0_201/jre /lib
...