多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Ruby 哈希 > 原文: [https://zetcode.com/lang/rubytutorial/hashes/](https://zetcode.com/lang/rubytutorial/hashes/) 在 Ruby 教程的这一部分中,我们将使用 Ruby 哈希。 ## Ruby 哈希定义 Ruby 哈希是键-值对的集合。 它类似于数组。 与数组不同,哈希可以将任意对象作为索引。 数组只能具有整数。 哈希值按插入相应键的顺序枚举其值。 哈希有时称为关联数组。 哈希是功能强大的集合。 他们有许多方法可供程序员用来完成工作。 ## Ruby 哈希创建 可以通过两种基本方式创建哈希:使用`new`关键字或哈希字面值。 ```ruby #!/usr/bin/ruby names = Hash.new names[1] = "Jane" names[2] = "Thomas" puts names ``` 第一个脚本创建一个哈希并将两个键值对添加到哈希对象中。 ```ruby names = Hash.new ``` 创建一个哈希对象。 ```ruby names[1] = "Jane" names[2] = "Thomas" ``` 我们将两对值添加到哈希中。 数字 1、2 是哈希的键。 键放在方括号内。 名称是属于键的值。 ```ruby puts names ``` `puts`方法将哈希的字符串表示形式打印到控制台。 它也是哈希的字符串字面值。 ```ruby $ ./create.rb {1=>"Jane", 2=>"Thomas"} ``` 从输出中,我们可以看到名称哈希的字面表示。 哈希以大括号为界。 键和值与`=>`字符配对。 `store`方法可用于使用某些值初始化哈希。 可以使用它代替方括号。 ```ruby #!/usr/bin/ruby names = Hash.new names.store(1, "Jane") names.store(2, "Thomas") names.store(3, "Rebecca") puts names ``` 我们有一个类似的脚本。 这次我们使用`store`方法。 该方法将给定键与给定值相关联,并将该对存储在哈希中。 ```ruby names.store(1, "Jane") ``` `store`方法的第一个参数是键,第二个参数是值。 在第三个脚本中,我们使用哈希字面值表示法创建哈希。 值用大括号括起来。 键值对与`=>`字符相关联。 ```ruby #!/usr/bin/ruby domains = { "de" => "Germany", "sk" => "Slovakia", "hu" => "Hungary", "us" => "United States", "no" => "Norway" } puts domains["de"] puts domains["sk"] ``` 我们创建具有 5 对的域哈希。 这次键和值都是字符串类型。 ```ruby domains = { "de" => "Germany", "sk" => "Slovakia", "hu" => "Hungary", "us" => "United States", "no" => "Norway" } ``` 这是哈希字面值表示法。 键值对放在大括号之间。 这些项目用逗号分隔。 使用`=>`字符组合将键与值关联。 ```ruby puts domains["de"] ``` 在这里,我们打印与`"de"`键关联的域名名称。 ```ruby $ ./create3.rb Germany Slovakia ``` 这是代码示例的输出。 ## Ruby 哈希基本操作 在本节中,我们介绍了一些用于 Ruby 哈希基础知识的方法。 ```ruby #!/usr/bin/ruby names = Hash.new names[1] = "Jane" names[2] = "Thomas" names[3] = "Robert" names[4] = "Julia" names[5] = "Rebecca" puts "The size of the hash is #{names.size}" puts names.keys.inspect puts names.values.inspect ``` 在上面的 Ruby 脚本中,我们创建具有五个值的哈希。 我们介绍了三种哈希方法。 ```ruby puts "The size of the hash is #{names.size}" ``` `size`方法返回哈希的大小。 它是`length`方法的同义词。 ```ruby puts names.keys.inspect puts names.values.inspect ``` `keys`方法返回哈希的所有键。 `values`方法以类似的方式返回哈希的所有值。 返回的数据为数组形式。 为了获得更可读的输出,我们还对返回的数组调用`inspect`方法。 ```ruby $ ./basic.rb The size of the hash is 5 [1, 2, 3, 4, 5] ["Jane", "Thomas", "Robert", "Julia", "Rebecca"] ``` 我们看到示例的输出。 请注意,最后两个方法的输出是两个数组。 本节的第二个示例介绍了三种不同的哈希方法。 ```ruby #!/usr/bin/ruby names1 = Hash.new names1[1] = "Jane" names1[2] = "Thomas" names1[3] = "Robert" names1[4] = "Julia" names1[5] = "Rebecca" names2 = names1.dup puts names1.eql? names2 puts names1.empty? names1.clear puts names1.empty? ``` Ruby 脚本创建一个名称哈希。 它在对象上调用三种哈希方法。 ```ruby names2 = names1.dup ``` 我们通过调用`dup`方法来创建哈希的副本。 该方法由父对象的哈希继承。 ```ruby puts names1.eql? names2 ``` `eql?`方法比较两个哈希对象。 在我们的例子中,哈希值是相等的,并且该行打印正确。 ```ruby puts names1.empty? ``` `empty?`方法检查哈希是否为空。 该行打印`false`,因为`names1`哈希包含五个项目。 ```ruby names1.clear puts names1.empty? ``` `clear`方法从哈希中删除所有项目。 连续调用`empty?`方法将返回`true`。 ```ruby $ ./basic2.rb true false true ``` 这是示例输出。 我们有一些方法可以确定哈希中是否存在键或值。 ```ruby #!/usr/bin/ruby domains = { :de => "Germany", :sk => "Slovakia", :no => "Norway", :us => "United States" } puts domains.has_key? :de puts domains.include? :no puts domains.key? :me puts domains.member? :sk puts domains.has_value? "Slovakia" puts domains.value? "Germany" ``` 我们用四个对创建一个域哈希。 键是符号。 通常将符号用作键,因为它们更有效。 ```ruby puts domains.has_key? :de puts domains.include? :no puts domains.key? :me puts domains.member? :sk ``` 在这里,我们有四种确定键是否在哈希中的方法。 他们都做同样的事。 它们是同义词。 ```ruby puts domains.has_value? "Slovakia" puts domains.value? "Germany" ``` 这两种方法检查两个字符串是否在哈希中。 ```ruby $ ./has.rb true true false true true true ``` 这是示例的输出。 在本节的最后一个示例中,我们将从哈希中读取值。 ```ruby #!/usr/bin/ruby stones = { 1 => "garnet", 2 => "topaz", 3 => "opal", 4 => "amethyst" } puts stones.fetch 1 puts stones[2] puts stones.values_at 1, 2, 3 ``` Ruby 脚本提供了三种用于读取哈希值的哈希方法。 ```ruby puts stones.fetch 1 ``` `fetch`方法读取给定键的值。 ```ruby puts stones[2] ``` 方括号可用于获取值。 在我们的例子中,该行将`"topaz"`打印到控制台。 ```ruby puts stones.values_at 1, 2, 3 ``` `values_at`方法可用于一步获得多个值。 该方法返回给定键的值的数组。 ```ruby $ ./read.rb garnet topaz garnet topaz opal ``` This is the output of the example. ## Ruby 哈希迭代 有几种方法可用于遍历 Ruby 哈希。 ```ruby #!/usr/bin/ruby stones = { 1 => "garnet", 2 => "topaz", 3 => "opal", 4 => "amethyst" } stones.each { |k, v| puts "Key: #{k}, Value: #{v}" } stones.each_key { |key| puts "#{key}" } stones.each_value { |val| puts "#{val}" } stones.each_pair { |k, v| puts "Key: #{k}, Value: #{v}" } ``` 在上面的示例中,我们介绍了四种方法。 我们使用它们显示哈希的所有键,值以及键和值。 ```ruby stones.each { |k, v| puts "Key: #{k}, Value: #{v}" } ``` `each`方法为哈希中的每个键调用给定的块,并将键值对作为参数传递。 ```ruby stones.each_key { |key| puts "#{key}" } ``` 我们使用`each_key`方法循环遍历哈希的所有键。 它们被打印到控制台。 ```ruby stones.each_value { |val| puts "#{val}" } ``` `each_value`可用于循环遍历哈希值。 ```ruby stones.each_pair { |k, v| puts "Key: #{k}, Value: #{v}" } ``` `each_pair`方法是`each`方法的同义词。 我们遍历石头哈希的键和值。 ```ruby $ ./loop.rb Key: 1, Value: garnet Key: 2, Value: topaz Key: 3, Value: opal Key: 4, Value: amethyst 1 2 3 4 garnet topaz opal amethyst Key: 1, Value: garnet Key: 2, Value: topaz Key: 3, Value: opal Key: 4, Value: amethyst ``` 输出显示石头哈希的键和值,键,值。 ## Ruby 删除哈希中的对 在以下示例中,我们将关注从哈希中删除对的方法。 这包括删除单个对的方法以及可以一步删除多个键值的方法。 ```ruby #!/usr/bin/ruby names = Hash.new names[1] = "Jane" names[2] = "Thomas" names[3] = "Robert" names[4] = "Julia" names[5] = "Rebecca" names.delete 4 names.shift puts names ``` 在脚本中,我们有两种方法:`delete`和`shift`。 `delete`方法删除并返回指定键的值。 `shift`方法从哈希中删除第一对。 它还以数组形式返回删除的对。 ```ruby names.delete 4 ``` 在这里,我们删除一对`4 => "Julia"`。 ```ruby names.shift ``` 该代码行删除了第一对,即`1 => "Jane"`。 ```ruby $ ./deleteitem.rb {2=>"Thomas", 3=>"Robert", 5=>"Rebecca"} ``` 在输出中,我们可以看到剩下的哈希对。 `reject`和`delete_if`方法可以从哈希中删除多对。 这些方法删除对块中给定条件返回`true`的对。 两种方法之间有重要区别。 `reject`方法适用于哈希的副本,而`delete_if`方法适用于原始哈希。 ```ruby #!/usr/local/bin/ruby names1 = Hash.new names1[1] = "Jane" names1[2] = "Thomas" names1[3] = "Robert" names1[4] = "Julia" names1[5] = "Rebecca" puts names1.reject { |k, v| v =~ /R.*/ } puts names1 puts names1.delete_if { |k, v| k<=3 } puts names1 ``` 该示例使用前面提到的方法删除多个对。 ```ruby puts names1.reject { |k, v| v =~ /R.*/ } ``` `reject`方法删除适合块中正则表达式的所有值。 返回修改后的哈希,并且原始哈希不会更改。 ```ruby puts names1 ``` 该行的输出确认原始哈希是完整的。 ```ruby puts names1.delete_if { |k, v| k<=3 } ``` 在这种情况下,我们将删除所有键小于或等于 3 的对。该方法将修改原始哈希。 ```ruby $ ./massdelete.rb {1=>"Jane", 2=>"Thomas", 4=>"Julia"} {1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia", 5=>"Rebecca"} {4=>"Julia", 5=>"Rebecca"} {4=>"Julia", 5=>"Rebecca"} ``` 示例的输出。 ## Ruby 在哈希中添加元素 Ruby 的`merge`和`update`方法将(键,值)对添加到哈希。 Ruby 具有用于添加哈希的方法。 ```ruby #!/usr/bin/ruby names1 = Hash.new names1[1] = "Jane" names1[2] = "Thomas" names2 = Hash.new names2[3] = "Robert" names2[4] = "Julia" names = names1.merge names2 puts names names = names1.update names2 puts names ``` 在 Ruby 脚本中,我们创建两个哈希。 然后我们在它们上应用`merge`和`update`方法。 ```ruby names = names1.merge names2 puts names ``` `names1`和`names2`哈希组合在一起。 结果分配给名称哈希。 我们打印新创建的哈希。 ```ruby $ ./merge.rb {1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"} {1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"} ``` 如我们所见,最终的哈希包含`names1`和`names2`哈希对。 ## Ruby 哈希`merge`和`merge!`方法 在最后一节中,我们回顾了一个常见的 Ruby 习惯用法。 几种 Ruby 方法的对应方法都以感叹号结尾。 此标记没有语法意义,表示方法修改了调用该方法的对象。 ```ruby #!/usr/bin/ruby names1 = Hash.new names1[1] = "Jane" names1[2] = "Thomas" names2 = Hash.new names2[3] = "Robert" names2[4] = "Julia" names = names1.merge names2 puts names puts names1 names = names1.merge! names2 puts names puts names1 ``` 我们将演示`merge`和`merge!`方法的区别。 ```ruby names = names1.merge names2 ``` `merge`不会修改`names1`哈希。 它可以在其副本上工作。 ```ruby names = names1.merge! names2 ``` `merge!`方法适用于原始哈希。 `names1`哈希已更改。 ```ruby $ ./merge2.rb {1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"} {1=>"Jane", 2=>"Thomas"} {1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"} {1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"} ``` 这是`merge2.rb`程序的输出。 在本章中,我们使用了 Ruby 哈希。