跳转至

Ruby 哈希

原文: https://zetcode.com/lang/rubytutorial/hashes/

在 Ruby 教程的这一部分中,我们将使用 Ruby 哈希。

Ruby 哈希定义

Ruby 哈希是键-值对的集合。 它类似于数组。 与数组不同,哈希可以将任意对象作为索引。 数组只能具有整数。 哈希值按插入相应键的顺序枚举其值。 哈希有时称为关联数组。

哈希是功能强大的集合。 他们有许多方法可供程序员用来完成工作。

Ruby 哈希创建

可以通过两种基本方式创建哈希:使用new关键字或哈希字面值。

#!/usr/bin/ruby

names = Hash.new
names[1] = "Jane"
names[2] = "Thomas"

puts names

第一个脚本创建一个哈希并将两个键值对添加到哈希对象中。

names = Hash.new

创建一个哈希对象。

names[1] = "Jane"
names[2] = "Thomas"

我们将两对值添加到哈希中。 数字 1、2 是哈希的键。 键放在方括号内。 名称是属于键的值。

puts names

puts方法将哈希的字符串表示形式打印到控制台。 它也是哈希的字符串字面值。

$ ./create.rb
{1=>"Jane", 2=>"Thomas"}

从输出中,我们可以看到名称哈希的字面表示。 哈希以大括号为界。 键和值与=>字符配对。

store方法可用于使用某些值初始化哈希。 可以使用它代替方括号。

#!/usr/bin/ruby

names = Hash.new
names.store(1, "Jane")
names.store(2, "Thomas")
names.store(3, "Rebecca")

puts names

我们有一个类似的脚本。 这次我们使用store方法。 该方法将给定键与给定值相关联,并将该对存储在哈希中。

names.store(1, "Jane")

store方法的第一个参数是键,第二个参数是值。

在第三个脚本中,我们使用哈希字面值表示法创建哈希。 值用大括号括起来。 键值对与=>字符相关联。

#!/usr/bin/ruby

domains = { "de" => "Germany",
            "sk" => "Slovakia",
            "hu" => "Hungary",
            "us" => "United States",
            "no" => "Norway"                       
          }

puts domains["de"]
puts domains["sk"]

我们创建具有 5 对的域哈希。 这次键和值都是字符串类型。

domains = { "de" => "Germany",
            "sk" => "Slovakia",
            "hu" => "Hungary",
            "us" => "United States",
            "no" => "Norway"                       
          }

这是哈希字面值表示法。 键值对放在大括号之间。 这些项目用逗号分隔。 使用=>字符组合将键与值关联。

puts domains["de"]

在这里,我们打印与"de"键关联的域名名称。

$ ./create3.rb 
Germany
Slovakia

这是代码示例的输出。

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 脚本中,我们创建具有五个值的哈希。 我们介绍了三种哈希方法。

puts "The size of the hash is #{names.size}"

size方法返回哈希的大小。 它是length方法的同义词。

puts names.keys.inspect
puts names.values.inspect

keys方法返回哈希的所有键。 values方法以类似的方式返回哈希的所有值。 返回的数据为数组形式。 为了获得更可读的输出,我们还对返回的数组调用inspect方法。

$ ./basic.rb
The size of the hash is 5
[1, 2, 3, 4, 5]
["Jane", "Thomas", "Robert", "Julia", "Rebecca"]

我们看到示例的输出。 请注意,最后两个方法的输出是两个数组。

本节的第二个示例介绍了三种不同的哈希方法。

#!/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 脚本创建一个名称哈希。 它在对象上调用三种哈希方法。

names2 = names1.dup

我们通过调用dup方法来创建哈希的副本。 该方法由父对象的哈希继承。

puts names1.eql? names2

eql?方法比较两个哈希对象。 在我们的例子中,哈希值是相等的,并且该行打印正确。

puts names1.empty?

empty?方法检查哈希是否为空。 该行打印false,因为names1哈希包含五个项目。

names1.clear
puts names1.empty?

clear方法从哈希中删除所有项目。 连续调用empty?方法将返回true

$ ./basic2.rb
true
false
true

这是示例输出。

我们有一些方法可以确定哈希中是否存在键或值。

#!/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"

我们用四个对创建一个域哈希。 键是符号。 通常将符号用作键,因为它们更有效。

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"

这两种方法检查两个字符串是否在哈希中。

$ ./has.rb
true
true
false
true
true
true

这是示例的输出。

在本节的最后一个示例中,我们将从哈希中读取值。

#!/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 脚本提供了三种用于读取哈希值的哈希方法。

puts stones.fetch 1

fetch方法读取给定键的值。

puts stones[2]

方括号可用于获取值。 在我们的例子中,该行将"topaz"打印到控制台。

puts stones.values_at 1, 2, 3

values_at方法可用于一步获得多个值。 该方法返回给定键的值的数组。

$ ./read.rb
garnet
topaz
garnet
topaz
opal

This is the output of the example.

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}" }

在上面的示例中,我们介绍了四种方法。 我们使用它们显示哈希的所有键,值以及键和值。

stones.each { |k, v| puts "Key: #{k}, Value: #{v}" }

each方法为哈希中的每个键调用给定的块,并将键值对作为参数传递。

stones.each_key { |key| puts "#{key}" }

我们使用each_key方法循环遍历哈希的所有键。 它们被打印到控制台。

stones.each_value { |val| puts "#{val}" }

each_value可用于循环遍历哈希值。

stones.each_pair { |k, v| puts "Key: #{k}, Value: #{v}" }

each_pair方法是each方法的同义词。 我们遍历石头哈希的键和值。

$ ./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 删除哈希中的对

在以下示例中,我们将关注从哈希中删除对的方法。 这包括删除单个对的方法以及可以一步删除多个键值的方法。

#!/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

在脚本中,我们有两种方法:deleteshiftdelete方法删除并返回指定键的值。 shift方法从哈希中删除第一对。 它还以数组形式返回删除的对。

names.delete 4

在这里,我们删除一对4 => "Julia"

names.shift

该代码行删除了第一对,即1 => "Jane"

$ ./deleteitem.rb
{2=>"Thomas", 3=>"Robert", 5=>"Rebecca"}

在输出中,我们可以看到剩下的哈希对。

rejectdelete_if方法可以从哈希中删除多对。 这些方法删除对块中给定条件返回true的对。 两种方法之间有重要区别。 reject方法适用于哈希的副本,而delete_if方法适用于原始哈希。

#!/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

该示例使用前面提到的方法删除多个对。

puts names1.reject { |k, v| v =~ /R.*/ }

reject方法删除适合块中正则表达式的所有值。 返回修改后的哈希,并且原始哈希不会更改。

puts names1

该行的输出确认原始哈希是完整的。

puts names1.delete_if { |k, v| k<=3 }

在这种情况下,我们将删除所有键小于或等于 3 的对。该方法将修改原始哈希。

$ ./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 的mergeupdate方法将(键,值)对添加到哈希。 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 脚本中,我们创建两个哈希。 然后我们在它们上应用mergeupdate方法。

names = names1.merge names2
puts names

names1names2哈希组合在一起。 结果分配给名称哈希。 我们打印新创建的哈希。

$ ./merge.rb
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}

如我们所见,最终的哈希包含names1names2哈希对。

Ruby 哈希mergemerge!方法

在最后一节中,我们回顾了一个常见的 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

我们将演示mergemerge!方法的区别。

names = names1.merge names2

merge不会修改names1哈希。 它可以在其副本上工作。

names = names1.merge! names2

merge!方法适用于原始哈希。 names1哈希已更改。

$ ./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 哈希。



回到顶部