Sorting/accessing 通过嵌套哈希数组
Sorting/accessing through an array of nested hashes
我有一个包含姓名和年龄的散列数组:
array = [ {"bill" => 12}, {"tom" => 13}, {"pat" => 14} ]
我意识到,通过调用 first
方法,会发生这种情况:
array.first # => {"bill" => 12}
在不定义 class 的情况下,我想做的是:
array.first.name # => "bill"
我该怎么做?
正在做:
def name
array[0].keys
end
将定义一个私有方法,不能在接收者上调用。
由于您的数组 array
由散列组成,当您执行 array.first
时,将返回一个散列 {"bill" => 12}
。
您现在可以定义可应用于 array.first
的方法 Hash#name
(一个哈希)
这里:
class Hash
def name
self.keys.first
end
end
array.first.name
# => "bill"
#to print all names
array.each{|a| puts a.name}
# bill
# tom
# pat
# or collect them in an Array
array.map(&:name)
# => ["bill", "tom", "pat"]
你有:
h = array.first #=> {"bill" => 12}
h.class #=> Hash
所以如果你想创建一个方法 first
,这样:
h.name #=> "bill"
您必须在其接收者 (h
) 的 class 上定义 name
,即 Hash
。 @shivam 已经向您展示了如何做到这一点,但是(正如@AndrewMarshall 在评论中指出的那样)它污染了 class Hash
。更好的方法是使用 Refinements
.
Refinements 是对 v2.0 的实验性添加,然后在 v2.1 中进行了修改并永久保留。它提供了一种通过提供 "a way to extend a class locally".
来避免 "monkey-patching" 的方法
我们可以这样做。首先,模块 M
:
中的 refine
Hash
module M
refine Hash do
def name
keys.first
end
end
end
只有在模块上调用关键字 using
后,细化才会生效:
h = {"bill" => 12}
puts h.name
#-> undefined method `name' for {"bill"=>12}:Hash (NoMethodError)
激活优化后,我们可以在 h
上调用 name
:
using M
h.name
#-> bill
改进适用于文件的其余部分,但不适用于其他文件中的代码。假设我们要将以下内容添加到当前文件中:
class A
def greeting(h)
puts "Hello, #{h.name}"
end
end
然后:
A.new.greeting({"bill" => 12})
#-> Hello, bill
我有一个包含姓名和年龄的散列数组:
array = [ {"bill" => 12}, {"tom" => 13}, {"pat" => 14} ]
我意识到,通过调用 first
方法,会发生这种情况:
array.first # => {"bill" => 12}
在不定义 class 的情况下,我想做的是:
array.first.name # => "bill"
我该怎么做?
正在做:
def name
array[0].keys
end
将定义一个私有方法,不能在接收者上调用。
由于您的数组 array
由散列组成,当您执行 array.first
时,将返回一个散列 {"bill" => 12}
。
您现在可以定义可应用于 array.first
的方法 Hash#name
(一个哈希)
这里:
class Hash
def name
self.keys.first
end
end
array.first.name
# => "bill"
#to print all names
array.each{|a| puts a.name}
# bill
# tom
# pat
# or collect them in an Array
array.map(&:name)
# => ["bill", "tom", "pat"]
你有:
h = array.first #=> {"bill" => 12}
h.class #=> Hash
所以如果你想创建一个方法 first
,这样:
h.name #=> "bill"
您必须在其接收者 (h
) 的 class 上定义 name
,即 Hash
。 @shivam 已经向您展示了如何做到这一点,但是(正如@AndrewMarshall 在评论中指出的那样)它污染了 class Hash
。更好的方法是使用 Refinements
.
Refinements 是对 v2.0 的实验性添加,然后在 v2.1 中进行了修改并永久保留。它提供了一种通过提供 "a way to extend a class locally".
来避免 "monkey-patching" 的方法我们可以这样做。首先,模块 M
:
refine
Hash
module M
refine Hash do
def name
keys.first
end
end
end
只有在模块上调用关键字 using
后,细化才会生效:
h = {"bill" => 12}
puts h.name
#-> undefined method `name' for {"bill"=>12}:Hash (NoMethodError)
激活优化后,我们可以在 h
上调用 name
:
using M
h.name
#-> bill
改进适用于文件的其余部分,但不适用于其他文件中的代码。假设我们要将以下内容添加到当前文件中:
class A
def greeting(h)
puts "Hello, #{h.name}"
end
end
然后:
A.new.greeting({"bill" => 12})
#-> Hello, bill