如何在Ruby中向现有哈希表中添加元素

109

在Ruby中添加一个已存在且被填充的哈希表中的key => value键值对,我正在阅读Apress的《Beginning Ruby》并刚刚完成了哈希章节。

我试图找到一种与数组相同的最简单的方法来实现哈希表中的相同结果:

x = [1, 2, 3, 4]
x << 5
p x
7个回答

211

如果你有一个哈希表,可以通过键名将项添加到其中:

hash = { }
hash[:a] = 'a'
hash[:a]
# => 'a'

就像[ ]创建一个空数组一样,{ }会创建一个空的哈希表。

数组按特定顺序具有零个或多个元素,其中元素可以重复。哈希表按键组织具有零个或多个元素,其中键不能重复,但存储在这些位置中的值可以重复。

Ruby中的哈希表非常灵活,可以使用几乎任何类型的键。这使其与其他语言中的字典结构不同。

请记住,哈希表键的具体属性通常很重要:

hash = { :a => 'a' }

# Fetch with Symbol :a finds the right value
hash[:a]
# => 'a'

# Fetch with the String 'a' finds nothing
hash['a']
# => nil

# Assignment with the key :b adds a new entry
hash[:b] = 'Bee'

# This is then available immediately
hash[:b]
# => "Bee"

# The hash now contains both keys
hash
# => { :a => 'a', :b => 'Bee' }

在Ruby on Rails中,HashWithIndifferentAccess会将符号(Symbol)和字符串(String)的访问方法自由转换,这可能会导致一些混淆。

你也可以使用几乎任何类型进行索引,包括类、数字或其他哈希表。

hash = { Object => true, Hash => false }

hash[Object]
# => true

hash[Hash]
# => false

hash[Array]
# => nil

哈希表可以转换为数组,反之亦然:

# Like many things, Hash supports .to_a
{ :a => 'a' }.to_a
# => [[:a, "a"]]

# Hash also has a handy Hash[] method to create new hashes from arrays
Hash[[[:a, "a"]]]
# => {:a=>"a"} 

在插入元素到哈希表中时,你可以一个个插入,也可以使用 merge 方法来合并哈希表:

{ :a => 'a' }.merge(:b => 'b')
# {:a=>'a',:b=>'b'}

请注意,这不会更改原始哈希表,而是返回一个新的。如果您想将一个哈希表合并到另一个哈希表中,可以使用merge!方法:

hash = { :a => 'a' }

# Returns the result of hash combined with a new hash, but does not alter
# the original hash.
hash.merge(:b => 'b')
# => {:a=>'a',:b=>'b'}

# Nothing has been altered in the original
hash
# => {:a=>'a'}

# Combine the two hashes and store the result in the original
hash.merge!(:b => 'b')
# => {:a=>'a',:b=>'b'}

# Hash has now been altered
hash
# => {:a=>'a',:b=>'b'}

像字符串和数组上的许多方法一样, ! 表示这是一个 原地 操作。


14
很多有价值的信息,但缺乏最基本的表述方式,正如@robbrit所回答的那样简单。 - danh
1
请编辑您的答案,确切地回答所提出的问题,最好是在顶部附近。如果我替您完成这项工作,那将是不礼貌的。 - Stephan
@Stephan 在顶部添加了一个更简洁的示例。 - tadman

66
my_hash = {:a => 5}
my_hash[:key] = "value"

现在它不起作用:line_item[:brain] = "HELLO",引发错误:无法写入未知属性“brain”。 - Anas Ansari

39

如果您想添加多个:

hash = {:a => 1, :b => 2}
hash.merge! :c => 3, :d => 4
p hash

9
x = {:ca => "Canada", :us => "United States"}
x[:de] = "Germany"
p x

我尝试使用以下代码实现: x['key'] = "value",但是我收到了错误消息。值得一提的是,我正在处理字符串。 - Tom
1
什么错误?除非你更具体,否则它可能是任何东西。 - tadman
它不起作用:line_item [: brain] =“HELLO”引发错误:无法写入未知属性brain - Anas Ansari
@AnasAnsari,看起来你的代码中line_item不是一个哈希表。 - Jeremy Roman

2
您可以使用自Ruby 2.0起可用的双星号运算符:
h = { a: 1, b: 2 }
h = { **h, c: 3 }
p h
# => {:a=>1, :b=>2, :c=>3}

1
hash = { a: 'a', b: 'b' }
 => {:a=>"a", :b=>"b"}
hash.merge({ c: 'c', d: 'd' })
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 

返回合并后的值。
hash
 => {:a=>"a", :b=>"b"} 

但不会修改调用对象。
hash = hash.merge({ c: 'c', d: 'd' })
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 
hash
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 

重新分配就行了。

IT不工作:line_item.merge({line_total: "YYEYAH"}). Raises: undefined method `merge' Line_item. - Anas Ansari

0
hash {}
hash[:a] = 'a'
hash[:b] = 'b'
hash = {:a => 'a' , :b = > b}

你可能需要从用户输入中获取键和值,因此你可以使用 Ruby 的 .to_sym 将字符串转换为符号,.to_i 将字符串转换为整数。
例如:

movies ={}
movie = gets.chomp
rating = gets.chomp
movies[movie.to_sym] = rating.to_int
# movie will convert to a symbol as a key in our hash, and 
# rating will be an integer as a value.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接