哈希 #

一、哈希概述 #

哈希(Hash)是Perl中用于存储键值对的数据结构,也称为关联数组。哈希变量以 % 开头。

1.1 创建哈希 #

perl
my %empty = ();
my %person = (
    name => "Tom",
    age  => 25,
    city => "Beijing",
);

1.2 旧式语法 #

perl
my %person = (
    "name", "Tom",
    "age", 25,
    "city", "Beijing",
);

1.3 胖箭头 vs 瘦箭头 #

perl
my %h1 = (a => 1, b => 2);
my %h2 = ("a", 1, "b", 2);

二、访问哈希元素 #

2.1 访问单个元素 #

使用 $ 和花括号:

perl
my %person = (
    name => "Tom",
    age  => 25,
    city => "Beijing",
);

print $person{name};
print $person{age};
print $person{city};

2.2 动态键名 #

perl
my $key = "name";
print $person{$key};

2.3 访问不存在的键 #

perl
my %person = (name => "Tom");
print $person{age};

print exists $person{age} ? "exists" : "not exists";

三、哈希操作 #

3.1 添加/修改元素 #

perl
my %person;
$person{name} = "Tom";
$person{age} = 25;
$person{city} = "Beijing";

$person{age} = 26;

3.2 删除元素 #

perl
my %person = (
    name => "Tom",
    age  => 25,
    city => "Beijing",
);

delete $person{city};

3.3 清空哈希 #

perl
%person = ();

四、遍历哈希 #

4.1 each循环 #

perl
my %person = (
    name => "Tom",
    age  => 25,
    city => "Beijing",
);

while (my ($key, $value) = each %person) {
    print "$key: $value\n";
}

4.2 keys遍历 #

perl
my %person = (
    name => "Tom",
    age  => 25,
    city => "Beijing",
);

foreach my $key (keys %person) {
    print "$key: $person{$key}\n";
}

4.3 values遍历 #

perl
my %person = (
    name => "Tom",
    age  => 25,
    city => "Beijing",
);

foreach my $value (values %person) {
    print "$value\n";
}

4.4 排序遍历 #

perl
my %person = (
    name => "Tom",
    age  => 25,
    city => "Beijing",
);

foreach my $key (sort keys %person) {
    print "$key: $person{$key}\n";
}

五、哈希函数 #

5.1 keys和values #

perl
my %person = (
    name => "Tom",
    age  => 25,
    city => "Beijing",
);

my @keys = keys %person;
my @values = values %person;
my $count = scalar keys %person;

5.2 exists #

检查键是否存在:

perl
my %person = (name => "Tom");

if (exists $person{name}) {
    print "name exists\n";
}

if (!exists $person{age}) {
    print "age not exists\n";
}

5.3 defined vs exists #

perl
my %h = (a => undef);

print exists $h{a} ? "exists" : "not exists";
print defined $h{a} ? "defined" : "undefined";
print exists $h{b} ? "exists" : "not exists";

5.4 delete #

删除键值对:

perl
my %person = (
    name => "Tom",
    age  => 25,
);

my $deleted = delete $person{age};
delete @person{qw(name city)};

六、哈希切片 #

6.1 获取多个值 #

perl
my %person = (
    name => "Tom",
    age  => 25,
    city => "Beijing",
    job  => "Engineer",
);

my @values = @person{qw(name age)};

6.2 设置多个值 #

perl
my %person;
@person{qw(name age city)} = ("Tom", 25, "Beijing");

七、哈希与数组转换 #

7.1 哈希转数组 #

perl
my %person = (
    name => "Tom",
    age  => 25,
);

my @pairs = %person;

7.2 数组转哈希 #

perl
my @pairs = ("name", "Tom", "age", 25);
my %person = @pairs;

7.3 使用map创建哈希 #

perl
my @keys = qw(a b c);
my @values = (1, 2, 3);
my %hash;
@hash{@keys} = @values;

八、常用技巧 #

8.1 统计频率 #

perl
my @items = qw(apple banana apple cherry banana apple);
my %count;
$count{$_}++ foreach @items;

while (my ($item, $num) = each %count) {
    print "$item: $num\n";
}

8.2 反转哈希 #

perl
my %original = (a => 1, b => 2, c => 3);
my %reversed = reverse %original;

8.3 合并哈希 #

perl
my %h1 = (a => 1, b => 2);
my %h2 = (c => 3, d => 4);
my %merged = (%h1, %h2);

8.4 哈希作为集合 #

perl
my @items = qw(a b c a d b);
my %seen;
my @unique = grep { !$seen{$_}++ } @items;

8.5 默认值 #

perl
my %count;
my $word = "hello";
$count{$word}++;
$count{$word} //= 0;
$count{$word}++;

九、复杂哈希 #

9.1 哈希的哈希 #

perl
my %users = (
    tom => {
        name => "Tom",
        age  => 25,
    },
    jerry => {
        name => "Jerry",
        age  => 30,
    },
);

print $users{tom}{name};

9.2 数组的哈希 #

perl
my %grades = (
    tom   => [85, 90, 78],
    jerry => [92, 88, 95],
);

print $grades{tom}[0];

十、实践练习 #

练习1:单词统计 #

perl
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;

my $text = "the quick brown fox jumps over the lazy dog the fox is quick";
my @words = split /\s+/, $text;

my %count;
$count{$_}++ foreach @words;

foreach my $word (sort keys %count) {
    say "$word: $count{$word}";
}

练习2:通讯录 #

perl
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;

my %contacts = (
    tom => {
        name  => "Tom Smith",
        email => "tom@example.com",
        phone => "123-456-7890",
    },
    jerry => {
        name  => "Jerry Brown",
        email => "jerry@example.com",
        phone => "098-765-4321",
    },
);

foreach my $id (keys %contacts) {
    my $contact = $contacts{$id};
    say "ID: $id";
    say "  Name: $contact->{name}";
    say "  Email: $contact->{email}";
    say "  Phone: $contact->{phone}";
}

练习3:配置解析 #

perl
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;

my @config_lines = (
    "host=localhost",
    "port=3306",
    "user=admin",
    "password=secret",
);

my %config;
foreach my $line (@config_lines) {
    my ($key, $value) = split /=/, $line, 2;
    $config{$key} = $value;
}

say "Host: $config{host}";
say "Port: $config{port}";
say "User: $config{user}";

十一、总结 #

本章学习了:

  • 哈希的创建和访问
  • 哈希元素操作(添加、修改、删除)
  • 哈希遍历方法
  • 常用哈希函数(keys、values、exists、delete)
  • 哈希切片
  • 复杂哈希结构

下一章将学习特殊变量。

最后更新:2026-03-27