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, "通过");
done_testing;

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

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

© . All rights reserved.