Ruby容器
所谓容器是指含有一个或多个对象引用的对象。
在开始实现之前,我们需要决定如何在SongList对象中存储歌曲列表。目前有3个明显的选择:(1)使用Ruby的Array(数组);(2)使用Ruby的Hash(散列表);(3)自定义列表结构。
数组类含有一组对象引用。每个对象引用占据数组中的一个位置,并由一个非负的整数索引来标识。
可以通过使用字面量(literal),或显示地创建Array对象,来创建数组。字面量数组(literal array)只不过是处于方括号中的一组对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | a = [ 3 . 14159 , "pie" , 99 ] a. class -> Array a.length -> 3 a[ 0 ] -> 3 . 14159 a[ 1 ] -> "pie" a[ 2 ] -> 99 a[ 3 ] -> nil b = Array . new b. class -> Array b.length -> 0 b[ 0 ] = "second" b[ 1 ] = "array" b -> [ "second" , "array" ] |
数组由[]操作符来进行索引。和Ruby的大多数操作符一样,它实际上是一个方法(Array类的一个实例方法),因此可以被子类重载。使用负整数访问数组,则从数组末端开始计数。
1 2 3 4 | a = [ 1 , 3 , 5 , 7 , 9 ] a[- 1 ] -> 9 a[- 2 ] -> 7 a[- 99 ] -> nil |
你也可以使用一对数字[start,count]来访问数组。这将返回一个包含从start开始的count个对象引用的新数组。
1 2 3 4 | a = [ 1 , 3 , 5 , 7 , 9 ] a[ 1 , 3 ] -> [ 3 , 5 , 7 ] a[ 3 , 1 ] -> [ 7 ] a[- 3 , 2 ] -> [ 5 , 7 ] |
最后,你还可以使用range来对数组进行索引,其开始和结束位置被两个或3个点分隔开。两个点的形式包含结束位置,而3个点的形式不包含。
1 2 3 4 5 | a = [ 1 , 3 , 5 , 7 , 9 ] a[ 1 .. 3 ] -> [ 3 , 5 , 7 ] a[ 1 ... 3 ] -> [ 3 , 5 ] a[ 3 .. 3 ] -> [ 7 ] a[- 3 ..- 1 ] -> [ 5 , 7 , 9 ] |
[]操作符有一个相应的[]=操作符,它可以设置数组中的元素。如果下表是单个整数,那么其位置上的元素将被赋值语句右边的东西说替换。造成的任何间隙将由nil来填充。
1 2 3 4 5 | a = [ 1 , 3 , 5 , 7 , 9 ] -> [ 1 , 3 , 5 , 7 , 9 ] a[ 1 ] = 'bat' -> [ 1 , "bat" , 5 , 7 , 9 ] a[- 3 ] = 'cat' -> [ 1 , "bat" , "cat" , 7 , 9 ] a[ 3 ] = [ 9 , 8 ] -> [ 1 , "bat" , "cat" ,[ 9 , 8 ], 9 ] a[ 6 ] = 99 -> [ 1 , "bat'," cat",[ 9 , 8 ], 9 , nil , 99 ] |
如果[]=的下标是两个数字(起点和长度)或者是range,那么原数组中的那些元素将被赋值语句右边的东西说替换。如果长度是0,那么赋值语句右边的东西将被插入到数组的起点位置之前,且不会删除任何元素。如果右边本身是一个数组,那么其元素将替换掉原数组对应位置上的东西。如果索引下标选择的元素个数和赋值语句右边的元素个数不一致,那么数组会自动调整其大小。
1 2 3 4 5 6 | a = [ 1 , 3 , 5 , 7 , 9 ] -> [ 1 , 3 , 5 , 7 , 9 ] a[ 2 , 2 ] = 'cat' -> [ 1 , 3 , "cat" , 9 ] a[ 2 , 0 ] = 'dog' -> [ 1 , 3 , "dog'," cat', 9 ] a[ 1 , 1 ] = [ 9 , 8 , 7 ] -> [ 1 , 9 , 8 , 7 , "dog" , "cat" , 9 ] a[ 0 .. 3 ] = [] -> [ "dog" , "cat" , 9 ] a[ 5 .. 6 ] = 99 , 98 -> [ "dog" , "cat" , 9 , nil , nil , 99 , 98 ] |
Hashes(也称关联数组、图或者词典)和数组的相似之处在于它们都是被索引的对象引用的集合。不过数组只能用整数来进行索引。不过数组只能用整数来进行索引,而hash可以用任何类型的对象来进行索引,比如字符串、正则表达式等等。当你将一个值存入hash时,其实需要提供两个对象,一个是索引(通常称为键(key)),另一个是值。随后你可以通过键去索引hash,以获得其对应的值。hash中的值可以是任意类型的对象。
下面的例子使用了hash字母符号表示法;处于花括号之间的key=>value配对的列表。
1 2 3 4 5 6 7 | h = { 'dog' => 'canine' , 'cat' => 'feline' , 'donkey' => 'asinine' } h.length -> 3 h[ 'dog' ] -> "canine" h[ 'cow' ] = 'bovine' h[ 12 ] = 'dodecine' h[ 'cat' ] = 99 h ->{ "cow" => "bovine" , "cat" = 99 , 12 => "dodecine" ,<br> "donkey" => "asinine" , "dog" => "canine" } |
和数组相比,hashed有一个突出的优点:可以用任何对象做索引。然后它也有一个突出的缺点:它的元素是无序的,因此很难使用hash来实现栈和队列。
hash是Ruby最常用的数据结构之一。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· 语音处理 开源项目 EchoSharp
· 《HelloGitHub》第 106 期
· Huawei LiteOS基于Cortex-M4 GD32F4平台移植
· mysql8.0无备份通过idb文件恢复数据过程、idb文件修复和tablespace id不一致处