当前位置: 首页 > 文档资料 > Perl6 入门指导 >

第六章 Perl6 散列

优质
小牛编辑
122浏览
2023-12-01

散列(哈希/联合数组)

散列,也称作联合数组(Associative Arrays),用于存储多个键值对,散列中的键(key)必须唯一而值(value)可以取任意值。

散列变量名必须以百分符号(%)开头。

tutorial/hash/create_hash.p6

#!/usr/bin/env perl6
use v6;

my %user_a = "fname", "Foo", "lname", "Bar";

my %user_b = 
    "fname" => "Foo", 
    "lname" => "Bar",
;

say %user_a{"fname"};
%user_a{"email"} = "foo@bar.com";
say %user_a{"email"};

say %user_b<lname>;

输出:

tutorial/hash/create_hash.p6.out

Foo
foo@bar.com
Bar

从散列中取值

tutorial/hash/print_hash.p6

#!/usr/bin/env perl6
use v6;

my %user = 
    "fname" => "Foo", 
    "lname" => "Bar",
    "email" => "foo@bar.com",
;

for %user.keys.sort -> $key {
    say "$key  %user{$key}";
}

输出:

tutorial/hash/print_hash.p6.out

email  foo@bar.com
fname  Foo
lname  Bar

多维散列

tutorial/hash/multi.p6

#!/usr/bin/env perl6
use v6;

my %xml;

%xml<person>[0] = 'Foo';
%xml<person>[1] = 'Bar';

say %xml.perl;

输出:

tutorial/hash/multi.p6.out

("person" => ["Foo", "Bar"]).hash

词频统计

tutorial/hash/count_words.p6

#!/usr/bin/env perl6
use v6;

my $filename = 'examples/words.txt';

my %counter;

my $fh = open $filename;
for $fh.lines -> $line {
    my @words = split /\s+/, $line;
    for @words -> $word {
        %counter{$word}++;
    }
}

for %counter.keys.sort -> $word {
    say "$word {%counter{$word}}";
}

散列用法总览

tutorial/hash/hash.p6

#!/usr/bin/env perl6
use v6;

# creating hashes
my %h1 = first => '1st', second => '2nd';

if %h1{'first'}.defined {
    say "the value of 'first' is defined";
}
if %h1<second>.defined {
    say "the value of 'second' is defined";
}

if %h1.exists('first') {
    say "the key 'first' exists in h2";
}

say %h1.exists('third') ?? "third exists" !! "third does not exist";

say %h1<first>;
say %h1<second>;

# TODO 以下方法尚未被实现
#my %h2{'a', 'b'} = ('A', 'B');
#say %h2.delete('a');
#say %h2.delete('a');

输出:

tutorial/hash/hash.p6.out

the value of 'first' is defined
the value of 'second' is defined
the key 'first' exists in h2
third does not exist
1st
2nd

“啜食”散列

tutorial/files/slurp_csv_file.p6

#!/usr/bin/env perl6
use v6;

my $filename = 'examples/phonebook.txt';

my @lines = lines $filename.IO;
for @lines -> $line {
    say "L: $line";
}

#my %phonebook = map {split ",", $_}, @lines;
#my %phonebook = map {$_.comb(/\w+/)}, @lines;

my %phonebook = slurp($filename).comb(/\w+/);

my $name = prompt "Name:";
say %phonebook{$name};

tutorial/phonebook.txt

Foo,123
Bar,78
Baz,12321

取出所有的键值对

tutorial/hash/print_hash_kv.p6

#!/usr/bin/env perl6
use v6;

my %user =
    "fname" => "Foo",
    "lname" => "Bar",
    "email" => "foo@bar.com",
;

for %user.kv -> $key, $value {
    say "$key  $value";
}

输出:

tutorial/hash/print_hash_kv.p6.out

fname  Foo
lname  Bar
email  foo@bar.com

取出所有的键

使用keys方法是我们遍历散列中所有键的另一种方法。

在Perl6中声明散列变量的方法与Perl5无异,只是在访问散列中单个值的时候仍然需要保留变量名前的百分符号(%)。也就是说,如果想访问一个散列变量中以“Foo”为键的值就需要使用%phone{"Foo"},也就是说如果标量变量$name的值为“Foo”,则我们也可以采用%phone{$name}这种写法。

前文中已经提出过,字符串中内嵌散列变量需要使用大括号来包裹。

tutorial/hash/loop_over_hash.p6

#!/usr/bin/env perl6
use v6;

my %phone = 
    "Foo" => 123,
    "Bar" => 456,
;

for keys %phone -> $name {
    say "$name %phone{$name}";
}

输出:

tutorial/hash/loop_over_hash.p6.out

Bar 456
Foo 123