列表和哈希
2015年12月3日
在许多编程环境中,现在通常将数据结构表示为列表和哈希映射的组合。大多数主要语言现在都提供了这些数据结构的标准版本,以及一系列丰富的操作,特别是集合管道,用于操作它们。这些数据结构非常灵活,允许我们以易于处理和操作的方式表示大多数形式的层次结构。 [1]
这种数据结构的本质是,通常存在两种复合数据类型
- 哈希映射是一种键值数据结构,可以称为关联数组、哈希表、映射或字典。
- 列表是简单的序列。它们与传统的数组略有不同,因为它们在添加或删除元素时会动态调整大小(不过,某些语言确实称它们为数组)。它们可以通过整数键进行索引。
树的叶子可以是任何其他元素,通常是语言中的基本基元(如整数和字符串),也可以是任何其他不能被视为列表或哈希的结构。
在大多数情况下,列表和哈希有单独的数据类型,因为它们的访问操作不同。但是,正如任何 lisper 都能告诉你的那样,很容易将哈希表示为键值对的列表。类似地,你可以将具有数字索引的哈希视为列表(这就是 Lua 表的行为)。
默认情况下,列表和哈希结构是无模式的,列表可以包含不同的元素,哈希可以包含任何键的组合。这使得数据结构非常灵活,但我们必须记住,当我们操作无模式数据结构时,我们几乎总是存在隐式模式,因为我们期望某些数据以某些键表示。
列表和哈希结构的优势在于,你可以使用通用操作来操作它,这些操作不知道实际存在的键。然后,这些操作可以用你想要操作的键进行参数化。通用操作通常被组织成集合管道,提供了许多导航功能,允许你从数据结构中提取所需的内容,而无需操作各个部分。
虽然通常使用灵活的哈希来表示记录,但你可以将使用定义的记录结构(或对象)的结构以与哈希相同的方式进行操作,如果这些记录结构提供了反射操作。虽然这种结构会限制你可以在其中放入的内容(这通常是一件好事),但使用通用操作来操作它非常有用。但这确实需要语言环境提供将记录查询为哈希的机制。
列表和哈希结构可以轻松地序列化,通常序列化为文本形式。JSON 是这种数据结构的特别有效的序列化形式,也是我的默认选择。通常使用 XML 来序列化列表和哈希结构,它可以很好地完成工作,但冗长且属性和元素之间的区别对于这些结构没有意义(尽管对于标记文本来说很有意义)。
尽管列表和哈希非常常见,但我有时希望我使用的是经过深思熟虑的树表示。这种模型可以提供更丰富的导航操作。在使用Nokogiri 中的序列化 XML 结构时,我发现能够使用 XPath 或 CSS 选择器来导航数据结构非常方便。对于较大的文档,这种通用路径规范非常方便。另一个问题是,在树中查找给定节点的父节点或祖先节点可能比应该的更麻烦。在现代语言中,丰富的列表和哈希作为标准设备的存在是我从 Fortran IV 开始编程以来编程生活中明确的改进之一,但没有必要止步于此。
致谢
David Johnston、Marzieh Morovatpasand、Peter Gillard-Moss、Philip Duldig、Rebecca Parsons、Ryan Murray 和 Steven Lowe 在我们的内部邮件列表中讨论了这篇文章。注释
1: 我发现没有通用的、跨语言的术语来描述这种数据结构很尴尬。我需要这样的术语,因此我渴望创造一个新词