Raku 中散列的键和值

Keys, values, etc. of hashes in Raku

Raku 中散列的键和值

今天,我们将看看 Hash 类的几个返回散列所有键或值或同时返回键和值的方法:

> my %h = H => 'Hydrogen', He => 'Helium', Li => 'Lithium';
{H => Hydrogen, He => Helium, Li => Lithium}

> %h.keys;
(H Li He)

> %h.values;
(Hydrogen Lithium Helium)

> %h.kv;
(H Hydrogen Li Lithium He Helium)

虽然你可能想直接进入 src/core/Hash.pm6 文件来查看方法的定义,但你会一无所获。 Hash 类是 Map 的子类,所有这些方法都定义在 src/core/Map.pm6 文件中。获取键和值很简单:

multi method keys(Map:D:) {
    Seq.new(Rakudo::Iterator.Mappy-keys(self))
}

multi method values(Map:D:) {
    Seq.new(Rakudo::Iterator.Mappy-values(self))
}

对于 kv 方法, 需要多做点工作:

multi method kv(Map:D:) {
    Seq.new(class :: does Rakudo::Iterator::Mappy) {
        has int $!on-value;

        method pull-one() is raw {
            ...
        }
        method skip-one() {
            ...
        }
        method push-all($target --> IterationEnd) {
            ...
        }
    }.new(self)
}

如您所见,该方法返回一个使用了一个实现了 Rakudo::Iterator::Mappy 角色的匿名类构建的序列。我们已经看到了这种方法与定义 pull-onepush-all 方法是如何结合使用的。

让我们看看另一套方法,pairs 和 antipairs。其中之一简单明了:

multi method pairs(Map:D:) {
    Seq.new(self.iterator)
}

另外一个使用了中间类:

multi method antipairs(Map:D:) {
    Seq.new(class :: does Rakudo::Iterator::Mappy) {
        method pull-one() {
            ...
        }
        method push-all($target --> IterationEnd) {
            ...
        }
    }.new(self)
}

两种方法都产生相同结构的结果:

> %h.antipairs
(Hydrogen => H Lithium => Li Helium => He)

> %h.pairs
(H => Hydrogen Li => Lithium He => Helium)
keys  values 
comments powered by Disqus