Perl 哈希和数组:基础知识

Perl 使使用哈希和数组操作复杂数据变得容易。 这是您入门需要知道的。
370 位读者喜欢这篇文章。
Programming keyboard.

Opensource.com

我时不时被问到我为什么如此喜欢用 Perl 编程。 当面问我,我会滔滔不绝地谈论 Perl 社区的人们——事实上,我已经不止一次在 Opensource.com 上这样做了更多 次,一次,我毫不掩饰许多我最亲密的朋友都是 Perl 爱好者。

从技术角度来看,我最欣赏 Perl 的功能之一是使用数组和哈希操作复杂数据的简易工具。 如果您是一位经验丰富的 Perl 开发人员,您一定对这些都了如指掌,但如果您是 Perl 新手或只是考虑学习它,那么本文正适合您。

数组

与其他许多语言一样,数组描述了一组有序的事物——它们可以是字符、数字,甚至是代码块。 该集合从零开始编号,并且与所有 Perl 变量一样,它们没有类型——甚至没有要求集合的所有成员都具有相同的类型。 要在当前代码范围内定义一个空数组,请使用 my

my @names;

要为数组分配一些值,只需将它们括在括号中即可。 您可以使用索引号检索它们。

my @names = ( 'Noel Andrews', 
              'Patricia Cohen', 
              'Leonard Collier', 
              'Andre Potter' );
print $names[2];    # Leonard Collier

请注意,@print 语句中是如何更改为 $ 的; 我希望它返回一个标量,一个单独的事物,而不是事物列表。 如果您想对整个数组执行操作,请使用 @

一个常见的用例是将一组单词分配给一个数组,例如一个句子的单词。 使用 qw 分配它们。 在此代码段中,我们将对它们进行排序并提取另一个元素。

my @words = qw(The quick brown fox jumped over the lazy dog);
print $names[4];   # jumped

my @sorted_array = sort @words;
print $sorted_array[2]  
# dog -- the capital letter forces The to the zeroth element!

如果您想丢弃数组的内容,只需将空值分配给它即可

@names = ();

通常您会想知道数组中有多少个元素; 只需将其称为标量,您就会得到它。

my @words = qw(The quick brown fox jumped over the lazy dog);
print scalar @words; # 9 -- there are other ways to get this, too.

forforeach 循环需要一个数组才能工作。 “对于列表中的每个事物,执行某些操作”是一种常见的循环结构,在 Perl 中,它们不必像许多其他语言中的 for 循环那样是数值计数。

my @words = qw(The quick brown fox jumped over the lazy dog);
foreach my $word (sort @words) {
    print $word.' ';
}
# The brown dog fox jumped lazy over quick the

我可以深入探讨更多内容:pushpop 用于从数组末尾添加和删除元素,unshiftshift 用于从数组开头添加和删除元素,以及 splice 用于从数组中间删除或替换元素。 但让我们继续讨论哈希。

哈希

许多语言都使用类似于 Perl 哈希的结构,它们实际上就是关联数组。 有些语言(Java、JavaScript、Go 和其他一些语言)称它们为映射; 其他语言(包括 PostScript)称它们为字典,而在 PHP 和 MUMPS 中,所有数组实际上都是关联数组,其行为有点像 Perl 哈希。 哈希是一种具有多对元素的数据结构——键和值。 键始终是字符串,但值可以是任何内容,包括代码。 它们以 % 为前缀

my %employee_jobs =  (
    'Zachary Vega' =>; 'Support Specialist I',
    'Nina Medina' => 'Technical Trainer II',
    'Ruth Holloway' => 'Developer II'
    );

与数组一样,将它们分配为空值将删除内容,但您也可以删除特定的键值对

delete $employee_jobs{'Zachary Vega'};

请注意,与数组一样,当引用特定元素时,您使用 $ 而不是 %,但您命名的元素用花括号而不是方括号括起来。

在哈希中创建新元素很容易——只需命名它并给它一个值,您就完成了

$employee_jobs{'Thomas Gallette'} = 'UI Developer II';

假设您想对哈希的每个成员执行某些操作。 还记得我之前说过 forforeach 需要一个数组吗? Perl 为您提供了一种方便的方法来获取哈希的键作为数组

foreach my $employee (sort keys %employee_jobs) {
    print $employee . ' - ' . $employee_jobs{$employee}; 
}

与数组不同,哈希是无序的,因此如果您想要按某种顺序排列,则需要实现它。 对键进行 sort 是一种常见的做法。

您可以创建哈希数组、数组哈希以及您可以想到的任何其他类型的复杂数据结构。 要了解有关这些的更多信息,请查看Perl 文档。 通过哈希和数组,您可以轻松地将一组复杂的关系数据拖入内存以进行操作。 多年前,当我处理图书馆数据时,这些非常方便。 您还可以使用 Perl 模块读取 YAMLJSON 数据,并将它们存储在数组/哈希数据结构中,当然也可以将此类结构写出以 YAML 或 JSON 格式存储。

单元测试以确保复杂的数据包包含应有的内容有点棘手。 Test::Deep 提供了用于深度比较的有用工具。

对数组和哈希的良好理解将使新的 Perl 开发人员走上伟大的道路。

User profile image.
Ruth Holloway 长期以来一直担任系统管理员和软件开发人员,早在 VAX 11/780 上就开始了她的职业生涯。 她职业生涯的很大一部分(到目前为止)都在为图书馆的技术需求服务,并且自 2008 年以来一直是 Koha 开源图书馆自动化套件的贡献者。 Ruth 目前是 Clearbuilt 的 Perl 开发人员和项目负责人。

4 条评论

谢谢你的介绍/回顾,Ruth。
我一直对关键字 'my' 的用途/含义只有一个模糊的概念,但它肯定用得很多。 我猜它是一种初始化方法?

是的。 my 将列出的变量声明为(词法上)对封闭的块、文件或 eval 是本地的,因此无论您在什么上下文中定义它,它都只对该代码块是本地的。 如果您在脚本中使用“strict”,正如您应该做的那样,那么您*必须*使用 my、our 或 local 来声明您的变量,否则,它们会在首次使用时自动使用隐含的“my”实例化——这可能会产生不可预测的结果。

希望您觉得这个小介绍有用!

回复 作者 Greg P

Test2 的 is() 用于测试深度结构,通常它可以满足我的需求。

基本上

use Test2::V0
is($deep_struc, $what_it_should_be, "pass");
done_testing;

当然 Test::Deep 也有效 - 只是另一种选择。

一篇非常好的文章。 很高兴看到 Perl 得到推广。

知识共享许可协议本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.