雷林鹏分享:Ruby 哈希(Hash)

本文深入讲解了Ruby语言中的哈希(Hash)数据结构,包括其创建、操作及内建方法的使用。介绍了如何通过键值对进行数据存储,以及如何遍历、查找和更新哈希中的元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  Ruby 哈希(Hash)

  哈希(Hash)是类似 "employee" => "salary" 这样的键值对的集合。哈希的索引是通过任何对象类型的任意键来完成的,而不是一个整数索引,其他与数组相似。

  通过键或值遍历哈希的顺序看起来是随意的,且通常不是按照插入顺序。如果您尝试通过一个不存在的键访问哈希,则方法会返回 nil。

  创建哈希

  与数组一样,有各种不同的方式来创建哈希。您可以通过 new 类方法创建一个空的哈希:

  months = Hash.new

  您也可以使用 new 创建带有默认值的哈希,不带默认值的哈希是 nil:

  months = Hash.new( "month" )

  or

  months = Hash.new "month"

  当您访问带有默认值的哈希中的任意键时,如果键或值不存在,访问哈希将返回默认值:

  #!/usr/bin/ruby

  months = Hash.new( "month" )

  puts "#{months[0]}"

  puts "#{months[72]}"

  这将产生以下结果:

  month

  month

  #!/usr/bin/ruby

  H = Hash["a" => 100, "b" => 200]

  puts "#{H['a']}"

  puts "#{H['b']}"

  这将产生以下结果:

  100

  200

  您可以使用任何的 Ruby 对象作为键或值,甚至可以使用数组,所以下面的实例是一个有效的实例:

  [1,"jan"] => "January"

  哈希内建方法

  我们需要有一个 Hash 对象的实例来调用 Hash 方法。下面是创建 Hash 对象实例的方式:

  Hash[[key =>|, value]* ] or

  Hash.new [or] Hash.new(obj) [or]

  Hash.new { |hash, key| block }

  这将返回一个使用给定对象进行填充的新的哈希。现在,使用创建的对象,我们可以调用任意可用的实例方法。例如:

  #!/usr/bin/ruby

  $, = ", "

  months = Hash.new( "month" )

  months = {"1" => "January", "2" => "February"}

  keys = months.keys

  puts "#{keys}"

  这将产生以下结果:

  2, 1

  下面是公共的哈希方法(假设 hash 是一个 Hash 对象):

  序号方法 & 描述

  1hash == other_hash

  检查两个哈希是否具有相同的键值对个数,键值对是否相互匹配,来判断两个哈希是否相等。

  2hash.[key]

  使用键,从哈希引用值。如果未找到键,则返回默认值。

  3hash.[key]=value

  把 value 给定的值与 key 给定的键进行关联。

  4hash.clear

  从哈希中移除所有的键值对。

  5hash.default(key = nil)

  返回 hash 的默认值,如果未通过 default= 进行设置,则返回 nil。(如果键在 hash 中不存在,则 [] 返回一个默认值。)

  6hash.default = obj

  为 hash 设置默认值。

  7hash.default_proc

  如果 hash 通过块来创建,则返回块。

  8hash.delete(key) [or]

  array.delete(key) { |key| block }

  通过 key 从 hash 中删除键值对。如果使用了块 且未找到匹配的键值对,则返回块的结果。把它与 delete_if进行比较。

  9hash.delete_if { |key,value| block }

  为 block 为 true 的每个块,从 hash 中删除键值对。

  10hash.each { |key,value| block }

  遍历 hash,为每个 key 调用一次 block,传递 key-value 作为一个二元素数组。

  11hash.each_key { |key| block }

  遍历 hash,为每个 key 调用一次 block,传递 key 作为参数。

  12hash.each_key { |key_value_array| block }

  遍历 hash,为每个 key 调用一次 block,传递 key 和 value 作为参数。

  13hash.each_key { |value| block }

  遍历 hash,为每个 key 调用一次 block,传递 value 作为参数。

  14hash.empty?

  检查 hash 是否为空(不包含键值对),返回 true 或 false。

  15hash.fetch(key [, default] ) [or]

  hash.fetch(key) { | key | block }

  通过给定的 key 从 hash 返回值。如果未找到 key,且未提供其他参数,则抛出 IndexError 异常;如果给出了 default,则返回 default;如果指定了可选的 block,则返回 block 的结果。

  16hash.has_key?(key) [or] hash.include?(key) [or]

  hash.key?(key) [or] hash.member?(key)

  检查给定的 key 是否存在于哈希中,返回 true 或 false。

  17hash.has_value?(value)

  检查哈希是否包含给定的 value。

  18hash.index(value)

  为给定的 value 返回哈希中的 key,如果未找到匹配值则返回 nil。

  19hash.indexes(keys)

  返回一个新的数组,由给定的键的值组成。找不到的键将插入默认值。该方法已被废弃,请使用 select。

  20hash.indices(keys)

  返回一个新的数组,由给定的键的值组成。找不到的键将插入默认值。该方法已被废弃,请使用 select。

  21hash.inspect

  返回哈希的打印字符串版本。

  22hash.invert

  创建一个新的 hash,倒置 hash 中的 keys 和 values。也就是说,在新的哈希中,hash 中的键将变成值,值将变成键。

  23hash.keys

  创建一个新的数组,带有 hash 中的键。/td>

  24hash.length

  以整数形式返回 hash 的大小或长度。

  25hash.merge(other_hash) [or]

  hash.merge(other_hash) { |key, oldval, newval| block }

  返回一个新的哈希,包含 hash 和 other_hash 的内容,重写 hash 中与 other_hash 带有重复键的键值对。

  26hash.merge!(other_hash) [or]

  hash.merge!(other_hash) { |key, oldval, newval| block }

  与 merge 相同,但实际上 hash 发生了变化。

  27hash.rehash

  基于每个 key 的当前值重新建立 hash。如果插入后值发生了改变,该方法会重新索引 hash。

  28hash.reject { |key, value| block }

  为 block 为 true 的每个键值对创建一个新的 hash。

  29hash.reject! { |key, value| block }

  与 reject 相同,但实际上 hash 发生了变化。

  30hash.replace(other_hash)

  把 hash 的内容替换为 other_hash 的内容。

  31hash.select { |key, value| block }

  返回一个新的数组,由 block 返回 true 的 hash 中的键值对组成。

  32hash.shift

  从 hash 中移除一个键值对,并把该键值对作为二元素数组返回。

  33hash.size

  以整数形式返回 hash 的 size 或 length。

  34hash.sort

  把 hash 转换为一个包含键值对数组的二维数组,然后进行排序。

  35hash.store(key, value)

  存储 hash 中的一个键值对。

  36hash.to_a

  从 hash 中创建一个二维数组。每个键值对转换为一个数组,所有这些数组都存储在一个数组中。

  37hash.to_hash

  返回 hash(self)。

  38hash.to_s

  把 hash 转换为一个数组,然后把该数组转换为一个字符串。

  39hash.update(other_hash) [or]

  hash.update(other_hash) {|key, oldval, newval| block}

  返回一个新的哈希,包含 hash 和 other_hash 的内容,重写 hash 中与 other_hash 带有重复键的键值对。

  40hash.value?(value)

  检查 hash 是否包含给定的 value。

  41hash.values

  返回一个新的数组,包含 hash 的所有值。

  42hash.values_at(obj, ...)

  返回一个新的数组,包含 hash 中与给定的键相关的值。

  (编辑:雷林鹏 来源:网络)

转载于:https://www.cnblogs.com/pengpeng1208/p/10190479.html

实验1:顺序基本操作 一、实验目的 1.学会定义线性的顺序存储类型,实现C程序的基本结构,对线性的一些基本操作和具体的函数定义。 2.掌握顺序的基本操作实现顺序插入删除查找以及求并集等运算。 3.掌握对多函数程序的输入、编辑、调试和运行过程。 二、实验要求 1.预习C语言中结构体的定义与基本操作方法。 2.对顺序的每个基本操作用单独的函数实现。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告。 三、实验内容: 1.编写程序实现顺序的下列基本操作(1)初始化顺序La。 (2)将La置为空(3)销毁La。 (4)在La中插入一个新的元素。 (5)删除La中的某一元素。 (6)在La中查找某元素,若找到,则返回它在La中第一次出现的位置,否则返回0。 (7)打印输出La中的元素值。 2.编写程序完成下面的操作(1)构造两个顺序线性La和Lb,其元素都按值非递减顺序排列。 (2)实现归并La和Lb得到新的顺序Lc,Lc的元素也按值非递减顺序排列。 (3)假设两个顺序线性La和Lb分别示两个集合A和B,利用 union_Sq操作实现A=A∪B。 四、思考与提高 假设两个顺序线性La和Lb分别示两个集合A和B,如何实现A=A ∩B ? 实验2:单链基本操作 一、 实验目的 1. 学会定义单链的结点类型,实现对单链的一些基本操作和具体的函数定义,了解并掌握单链的类定义以及成员函数的定义与调用。 2. 掌握单链基本操作及两个有序归并、单链逆置等操作实现。 二 、实验要求 1.预习C语言中结构体的定义与基本操作方法。 2.对单链的每个基本操作用单独的函数实现。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告。 三、实验内容 1.编写程序完成单链的下列基本操作(1)初始化单链La。 (2)在La中第i个元素之前插入一个新结点。 (3)删除La中的第i个元素结点。 (4)在La中查找某结点并返回其位置。 (5)打印输出La中的结点元素值。 2 .构造两个带有头结点的有序单链La、Lb,编写程序实现将La、Lb合并成一个有序单链Lc。 合并思想是:程序需要3个指针:pa、pb、pc,其中pa,pb分别指向La与Lb中当前待比较插入的结点,pc 指向Lc中当前最后一个结点。依次扫描La和Lb中的元素,比较当前元素的值,将较小者链接到*pc之后,如此重复直到La或Lb结束为止,再将另一个链余下的内容链接到pc所指的结点之后。 3.构造一个单链L,其头结点指针为head,编写程序实现将L逆置。(即最后一个结点变成第一个结点,原来倒数第二个结点变成第二个结点,如此等等。) 四、思考与提高 1.如果上面实验内容2中合并的内不允许有重复的数据该如何操作? 2.如何将一个带头结点的单链La分解成两个同样结构的单链Lb,Lc,使得Lb中只含La中奇数结点,Lc中含有La的偶数结点? 实验3:循环队列基本操作 一 、实验目的 1.熟悉并能实现循环队列的定义和基本操作。 2.了解用队列解决实际用问题。 二、实验要求 1.进行队列的基本操作时要注意队列“先进先出”的特性。 2.复习关于队列操作的基础知识。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告。 三、实验内容 1.任意输入队列长度和队列中的元素值,构造一个顺序循环队列,对其进行清空、插入新元素、返回队头元素以及删除队头元素操作。 2.约瑟夫环的实现:设有n个人围坐在圆桌周围,现从某个位置 i 上的人开始报数,数到 m 的人就站出来。下一个人,即原来的第m+1个位置上的人,又从1开始报数,再是数到m的人站出来。依次重复下去,直到全部的人都站出来,按出列的先后又可得到一个新的序列。由于该问题是由古罗马著名的史学家Josephus提出的问题演变而来,所以通常称为Josephus 问题。 例如:当n=8,m=4,i=1时,得到的新序列为: 4,8,5,2,1,3,7,6 编写程序选择循环队列作为存储结构模拟整个过程,并依次输出出列的各人的编号。 实验4:矩阵的压缩存储及相关操作 (第11周星期三7、8节) 一 、实验目的 1.掌握下三角矩阵的输入、输出、转置算法。 2.理解稀疏矩阵的三元组类型定义,掌握稀疏矩阵的输入、输出、转置算法。 二 、实验要求 1.认真阅读和掌握本实验的算法思想。 2.编写完整程序完成下面的实验内容并上机运行。 三、实验内容 1.所谓上(下)三角矩阵是指矩阵的下(上)三角中的元素均为常数或零的n阶矩阵。此时除了存储上(下)三角矩阵中的元素之外再加一个存储常数的空间即可。三角矩阵中的重复元素c可共享一个存储空间,其余的元素正好有n×(n+1)/2个,因此,三角矩阵可压缩到向量Sa[0……n×(n+1)/2]中,其中c存放在向量的最后一个分量中。用向量Sa[0……n×(n+1)/2]压缩存储下三角矩阵,编写程序任意输入一个下三角矩阵,对其进行转置,输出转置后的矩阵。 2.用三元组顺序压缩存储稀疏矩阵,编写程序任意输入一个稀疏矩阵,对其进行转置,输出转置后的矩阵。 四、思考与提高 如何计算一个三元组示的稀疏矩阵对角线元素之和以及两个三元组示的稀疏矩阵的乘积? 实验5:二叉树的建立及遍历 (第十三周星期三7、8节) 一 、实验目的 1.学会实现二叉树结点结构和对二叉树的基本操作。 2.掌握对二叉树每种操作的具体实现,学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。 二 、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.编写完整程序完成下面的实验内容并上机运行。 3.整理并上交实验报告。 三、实验内容 1.编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归遍历算法(前序、中序、后序)对这棵二叉树进行遍历并计算出二叉树的高度。 2 .编写程序生成下面所示的二叉树,并采用中序遍历的非递归算法对此二叉树进行遍历 四、思考与提高 1.如何计算二叉链存储的二叉树中度数为1的结点数? 2.已知有—棵以二叉链存储的二叉树,root指向根结点,p指向二叉树中任一结点,如何求从根结点到p所指结点之间的路径? 实验6:二分查找Hash查找算法的程序实现 (第十五三周星期三7、8节) 一、 实验目的 1 .熟练掌握二分查找算法并能在有序中进行查找操作。 2. 掌握Hash的相关算法。 二 、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.复习顺序及二叉树的基本操作过程。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告。 三、实验内容 1.二分查找又称为折半查找,它要求要查找的顺序必须是有序,即中结点按关键字有序.并且要用顺序存储结构。 基本思想是:首先将给定值key与中中间位置记录的关键字相比较,若二者相等,则查找成功,否则根据比较的结果确定下次查找的范围是在中间记录的前半部分还是后半部分,然后在新的查找范围内进行同样的查找,如此重复下去,直到在中找到关键字与给定值相等的记录,或者确定中没有这样的记录。 编写程序构造一个有序La,从键盘接收一个关键字key,用二分查找法在La 中查找key,若找到则提示查找成功并输出key所在的位置,否则提示没有找到信息。 2.编写程序实现Hash建立删除插入以及查找操作程序包含主要功能函数有: Hash( ):计算哈希地址 InitialHash( ):初始化哈希 SearchHash( ):在哈希查找关键字 InsertHash( ):向哈希插入关键字 DeleteHash( )删除哈希中某一关键字 PrintHash ( ):打印输出哈希 四、思考与提高 如何利用二分查找算法在一个有序插入一个元素x,并保持的有序性? 实验7:至少三种排序算法的程序实现 (第十六周星期三7、8节) 一、 实验目的 1.掌握简单插入排序、冒泡排序、快速排序、堆排序以及归并排序的算法并加以用。 2.对各种查找、排序技术的时间、空间复杂性有进一步认识。 二 、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.编写完整程序完成下面的实验内容并上机运行。 3.整理并上交实验报告。 三、实验内容 编写程序实现下述五种算法至少三种,并用以下无序序列加以验证: 49,38,65,97,76,13,27,49 1.简单插入排序 2.冒泡排序 3.快速排序 4.归并排序 5.堆排序 四、思考与提高 1.设有1000个无序的元素,希望用最快的速度挑出其中前10个最大的元素,采用哪一种排序方法最好?为什么? 2.如何构造一种排序方法,使五个整数至多用七次比较就可以完成排序任务? 实验8:集成实验 一、 实验目的 目的:扩大编程量,完成模块化程序设计的全过程。 二 、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.编写完整程序完成下面的实验内容并上机运行。 3.整理并上交实验报告。 三、实验内容 将已经实现的模块装配在一起,由菜单进行管理,形成一个小型多功能软件。 while(1){ menuList(); scanf(&n); switch(n){ case 1:……;break; case 2:……;break; . . case 0:return; } } 如: • MenuSelect( ){ int select; SqList A , B , C ; MenuList( ); /* 打印菜单 */ scanf(“%d”,&select;); switch(select){ case 1: InitList_Sq( &A ); break; case 2: InitList_Sq( &B ); break; case 3: Insert(&A);break; case 4: Insert(&B );break; case 5: Union(&A ,B);break; ………….. default: printf(“\n ERROR\n”); } } 四、思考与提高 1. 优化已完成的程序,使整个实验形成至少三级菜单管理; 2.美化输出界面,使得操作友好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值