Hash
class Hash
Parent:ObjectIncluded modules:Enumerable
哈希是一个字典式的唯一键及其值的集合。也称为关联数组,它们与数组类似,但在数组使用整数作为其索引的情况下,Hash允许您使用任何对象类型。
哈希枚举它们的值的顺序是相应的键被插入。
哈希可以通过使用其隐式形式轻松创建:
grades = { "Jane Doe" => 10, "Jim Doe" => 6 }
哈希允许替代符号键的语法。代替
options = { :font_size => 10, :font_family => "Arial" }
你可以把它写成:
options = { font_size: 10, font_family: "Arial" }
每个已命名的密钥都是您可以在哈希中访问的符号:
options[:font_size] # => 10
哈希也可以通过它的:: new方法创建:
grades = Hash.new
grades["Dorothy Doe"] = 9
哈希具有访问哈希中不存在的键时返回的默认值
。如果未使用默认值
nil
。您可以通过将其作为参数发送到:: new来设置默认值
:
grades = Hash.new(0)
或者使用default =方法:
grades = {"Timmy Doe" => 8}
grades.default = 0
在哈希中访问值需要使用其密钥:
puts grades["Jane Doe"] # => 0
常见用途
哈希是表示数据结构的简单方法,例如
books = {}
books[:matz] = "The Ruby Programming Language"
books[:black] = "The Well-Grounded Rubyist"
散列也常被用作在函数中命名参数的一种方式。请注意,下面不使用括号。如果散列是方法调用的最后一个参数,则不需要花括号,从而创建一个非常干净的界面:
Person.create(name: "John Doe", age: 27)
def self.create(params)
@name = params[:name]
@age = params[:age]
end
哈希键
当两个对象的hash
值相同且两个对象彼此相同时,两个对象引用相同的散列键eql?
。
如果重写hash
和eql?
方法以提供有意义的行为,用户定义的类可以用作散列键。默认情况下,单独的实例引用单独的散列键。
典型的实现hash
是基于对象的数据,而eql?
通常是重写为重写的==
方法:
class Book
attr_reader :author, :title
def initialize(author, title)
@author = author
@title = title
end
def ==(other)
self.class === other and
other.author == @author and
other.title == @title
end
alias eql? ==
def hash
@author.hash ^ @title.hash # XOR
end
end
book1 = Book.new 'matz', 'Ruby in a Nutshell'
book2 = Book.new 'matz', 'Ruby in a Nutshell'
reviews = {}
reviews[book1] = 'Great reference!'
reviews[book2] = 'Nice and compact!'
reviews.length #=> 1
另见Object#hash和Object#eql?
公共类方法
Hash key, value, ... → new_hash Show source
Hash[ [ key, value, ... ] ] → new_hash
Hash object → new_hash
创建一个用给定对象填充的新散列。
类似于文字。在第一种形式中,键和值是成对出现的,所以必须有偶数个参数。{ key => value, ... }
第二种和第三种形式采用单个参数,它可以是键值对的数组,也可以是可转换为散列的对象。
Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200}
Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
static VALUE
rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
{
VALUE hash, tmp;
int i;
if (argc == 1) {
tmp = rb_hash_s_try_convert(Qnil, argv[0]
if (!NIL_P(tmp)) {
hash = hash_alloc(klass
if (RHASH(tmp)->ntbl) {
RHASH(hash)->ntbl = st_copy(RHASH(tmp)->ntbl
}
return hash;
}
tmp = rb_check_array_type(argv[0]
if (!NIL_P(tmp)) {
long i;
hash = hash_alloc(klass
for (i = 0; i < RARRAY_LEN(tmp ++i) {
VALUE e = RARRAY_AREF(tmp, i
VALUE v = rb_check_array_type(e
VALUE key, val = Qnil;
if (NIL_P(v)) {
#if 0 /* refix in the next release */
rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)",
rb_builtin_class_name(e), i
#else
rb_warn("wrong element type %s at %ld (expected array)",
rb_builtin_class_name(e), i
rb_warn("ignoring wrong elements is deprecated, remove them explicitly"
rb_warn("this causes ArgumentError in the next release"
continue;
#endif
}
switch (RARRAY_LEN(v)) {
default:
rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)",
RARRAY_LEN(v)
case 2:
val = RARRAY_AREF(v, 1
case 1:
key = RARRAY_AREF(v, 0
rb_hash_aset(hash, key, val
}
}
return hash;
}
}
if (argc % 2 != 0) {
rb_raise(rb_eArgError, "odd number of arguments for Hash"
}
hash = hash_alloc(klass
if (argc > 0) {
RHASH(hash)->ntbl = st_init_table_with_size(&objhash, argc / 2
}
for (i=0; i<argc; i+=2) {
rb_hash_aset(hash, argv[i], argv[i + 1]
}
return hash;
}
new → new_hash Show source
new(obj) → new_hash
new {|hash, key| block } → new_hash
返回一个新的空的散列。如果随后通过与哈希条目不对应的键访问此哈希,则返回的值取决于new
用于创建哈希的样式。在第一种形式中,访问返回nil
。如果指定obj
,则此单个对象将用于所有默认值
。如果指定了一个块,将使用散列对象和键调用它,并返回默认值
。如果需要,块的责任是将值存储在哈希中。
h = Hash.new("Go Fish")
h["a"] = 100
h["b"] = 200
h["a"] #=> 100
h["c"] #=> "Go Fish"
# The following alters the single default object
h["c"].upcase! #=> "GO FISH"
h["d"] #=> "GO FISH"
h.keys #=> ["a", "b"]
# While this creates a new default object each time
h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
h["c"] #=> "Go Fish: c"
h["c"].upcase! #=> "GO FISH: C"
h["d"] #=> "Go Fish: d"
h.keys #=> ["c", "d"]
static VALUE
rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
{
VALUE ifnone;
rb_hash_modify(hash
if (rb_block_given_p()) {
rb_check_arity(argc, 0, 0
ifnone = rb_block_proc(
SET_PROC_DEFAULT(hash, ifnone
}
else {
rb_check_arity(argc, 0, 1
ifnone = argc == 0 ? Qnil : argv[0];
RHASH_SET_IFNONE(hash, ifnone
}
return hash;
}
try_convert(obj) → hash or nil Show source
尝试使用#to_hash方法将obj
转换为散列。如果因任何原因无法转换obj,
则返回转换后的散列或nil 。
Hash.try_convert{1=>2}) # => {1=>2}
Hash.try_convert("1=>2") # => nil
static VALUE
rb_hash_s_try_convert(VALUE dummy, VALUE hash)
{
return rb_check_hash_type(hash
}
Public Instance Methods
hash < other → true or false Show source
返回true
如果哈希
是的子集等
。
h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 < h2 #=> true
h2 < h1 #=> false
h1 < h1 #=> false
static VALUE
rb_hash_lt(VALUE hash, VALUE other)
{
other = to_hash(other
if (RHASH_SIZE(hash) >= RHASH_SIZE(other)) return Qfalse;
return hash_le(hash, other
}
hash <= other → true or false Show source
如果散列
是其他
或等于其他的
子集,则返回true
。
h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 <= h2 #=> true
h2 <= h1 #=> false
h1 <= h1 #=> true
static VALUE
rb_hash_le(VALUE hash, VALUE other)
{
other = to_hash(other
if (RHASH_SIZE(hash) > RHASH_SIZE(other)) return Qfalse;
return hash_le(hash, other
}
hsh == other_hash → true or false Show source
Equality - 如果两个哈希每个包含相同数量的键并且每个键 - 值对等于(根据Object#==
)另一个哈希中的相应元素,则两个哈希相等。
h1 = { "a" => 1, "c" => 2 }
h2 = { 7 => 35, "c" => 2, "a" => 1 }
h3 = { "a" => 1, "c" => 2, 7 => 35 }
h4 = { "a" => 1, "d" => 2, "f" => 35 }
h1 == h2 #=> false
h2 == h3 #=> true
h3 == h4 #=> false
不会比较每个哈希的顺序。
h1 = { "a" => 1, "c" => 2 }
h2 = { "c" => 2, "a" => 1 }
h1 == h2 #=> true
static VALUE
rb_hash_equal(VALUE hash1, VALUE hash2)
{
return hash_equal(hash1, hash2, FALSE
}
hash > other → true or false Show source
如果其他
是散列的
子集,则返回true
。
h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 > h2 #=> false
h2 > h1 #=> true
h1 > h1 #=> false
static VALUE
rb_hash_gt(VALUE hash, VALUE other)
{
other = to_hash(other
if (RHASH_SIZE(hash) <= RHASH_SIZE(other)) return Qfalse;
return hash_le(other, hash
}
hash >= other → true or false Show source
返回true
如果其他
的子集的哈希
或等于哈希
。
h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 >= h2 #=> false
h2 >= h1 #=> true
h1 >= h1 #=> true
static VALUE
rb_hash_ge(VALUE hash, VALUE other)
{
other = to_hash(other
if (RHASH_SIZE(hash) < RHASH_SIZE(other)) return Qfalse;
return hash_le(other, hash
}
hshkey → value Show source
元素参考 - 检索与键
对象相对应的值
对象。如果找不到,则返回默认值
(详见Hash::new
参考资料)。
h = { "a" => 100, "b" => 200 }
h["a"] #=> 100
h["c"] #=> nil
VALUE
rb_hash_aref(VALUE hash, VALUE key)
{
st_data_t val;
if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
return rb_hash_default_value(hash, key
}
return (VALUE)val;
}
hshkey = value → value Show source
元素分配
将给定的值value
与由给定的关键字联系起来key
。
h = { "a" => 100, "b" => 200 }
h["a"] = 9
h["c"] = 4
h #=> {"a"=>9, "b"=>200, "c"=>4}
h.store("d", 42) #=> 42
h #=> {"a"=>9, "b"=>200, "c"=>4, "d"=>42}
key
在作为密钥使用时不应改变其值(unfrozen String
因为密钥将被复制并冻结)。
a = "a"
b = "b".freeze
h = { a => 100, b => 200 }
h.key(100).equal? a #=> false
h.key(200).equal? b #=> true
VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{
int iter_lev = RHASH_ITER_LEV(hash
st_table *tbl = RHASH(hash)->ntbl;
rb_hash_modify(hash
if (!tbl) {
if (iter_lev > 0) no_new_key(
tbl = hash_tbl(hash
}
if (tbl->type == &identhash || rb_obj_class(key) != rb_cString) {
RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val
}
else {
RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val
}
return val;
}
any? { |(key, value)| block } → true or false Show source
另请参阅Enumerable#any?
static VALUE
rb_hash_any_p(VALUE hash)
{
VALUE ret = Qfalse;
if (RHASH_EMPTY_P(hash)) return Qfalse;
if (!rb_block_given_p()) {
/* yields pairs, never false */
return Qtrue;
}
if (rb_block_arity() > 1)
rb_hash_foreach(hash, any_p_i_fast, (VALUE)&ret
else
rb_hash_foreach(hash, any_p_i, (VALUE)&ret
return ret;
}
assoc(obj) → an_array or nil Show source
通过哈希比较obj
和密钥使用进行搜索==
。返回键值对(两个元素数组)或者nil
如果找不到匹配。查看Array#assoc
。
h = {"colors" => ["red", "blue", "green"],
"letters" => ["a", "b", "c" ]}
h.assoc("letters") #=> ["letters", ["a", "b", "c"]]
h.assoc("foo") #=> nil
VALUE
rb_hash_assoc(VALUE hash, VALUE key)
{
st_table *table;
const struct st_hash_type *orighash;
VALUE args[2];
if (RHASH_EMPTY_P(hash)) return Qnil;
table = RHASH(hash)->ntbl;
orighash = table->type;
if (orighash != &identhash) {
VALUE value;
struct reset_hash_type_arg ensure_arg;
struct st_hash_type assochash;
assochash.compare = assoc_cmp;
assochash.hash = orighash->hash;
table->type = &assochash;
args[0] = hash;
args[1] = key;
ensure_arg.hash = hash;
ensure_arg.orighash = orighash;
value = rb_ensure(lookup2_call, (VALUE)&args, reset_hash_type, (VALUE)&ensure_arg
if (value != Qundef) return rb_assoc_new(key, value
}
args[0] = key;
args[1] = Qnil;
rb_hash_foreach(hash, assoc_i, (VALUE)args
return args[1];
}
clear → hsh Show source
从hsh中
删除所有键值对。
h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200}
h.clear #=> {}
VALUE
rb_hash_clear(VALUE hash)
{
rb_hash_modify_check(hash
if (!RHASH(hash)->ntbl)
return hash;
if (RHASH(hash)->ntbl->num_entries > 0) {
if (RHASH_ITER_LEV(hash) > 0)
rb_hash_foreach(hash, clear_i, 0
else
st_clear(RHASH(hash)->ntbl
}
return hash;
}
compact → new_hash Show source
返回删除了零值/密钥对的新散列
h = { a: 1, b: false, c: nil }
h.compact #=> { a: 1, b: false }
h #=> { a: 1, b: false, c: nil }
static VALUE
rb_hash_compact(VALUE hash)
{
VALUE result = rb_hash_new(
if (!RHASH_EMPTY_P(hash)) {
rb_hash_foreach(hash, set_if_not_nil, result
}
return result;
}
compact! → hsh Show source
从哈希中删除所有的零值。返回散列。
h = { a: 1, b: false, c: nil }
h.compact! #=> { a: 1, b: false }
static VALUE
rb_hash_compact_bang(VALUE hash)
{
rb_hash_modify_check(hash
if (RHASH(hash)->ntbl) {
st_index_t n = RHASH(hash)->ntbl->num_entries;
rb_hash_foreach(hash, delete_if_nil, hash
if (n != RHASH(hash)->ntbl->num_entries)
return hash;
}
return Qnil;
}
compare_by_identity → hsh Show source
使hsh
通过他们的身份比较它的密钥,即它将认为完全相同的对象作为相同的密钥。
h1 = { "a" => 100, "b" => 200, :c => "c" }
h1["a"] #=> 100
h1.compare_by_identity
h1.compare_by_identity? #=> true
h1["a".dup] #=> nil # different objects.
h1[:c] #=> "c" # same symbols are all same.
static VALUE
rb_hash_compare_by_id(VALUE hash)
{
if (rb_hash_compare_by_id_p(hash)) return hash;
rb_hash_modify(hash
RHASH(hash)->ntbl->type = &identhash;
rb_hash_rehash(hash
return hash;
}
compare_by_identity? → true or false Show source
如果hsh
将按其身份比较其键,则返回true
。另见Hash#compare_by_identity
。
VALUE
rb_hash_compare_by_id_p(VALUE hash)
{
if (!RHASH(hash)->ntbl)
return Qfalse;
if (RHASH(hash)->ntbl->type == &identhash) {
return Qtrue;
}
return Qfalse;
}
default(key=nil) → obj Show source
返回默认值,如果key
不存在于hsh中,
则返回hsh
返回的值。另见Hash::newH
和ash#default=
。
h = Hash.new #=> {}
h.default #=> nil
h.default(2) #=> nil
h = Hash.new("cat") #=> {}
h.default #=> "cat"
h.default(2) #=> "cat"
h = Hash.new {|h,k| h[k] = k.to_i*10} #=> {}
h.default #=> nil
h.default(2) #=> 20
static VALUE
rb_hash_default(int argc, VALUE *argv, VALUE hash)
{
VALUE args[2], ifnone;
rb_check_arity(argc, 0, 1
ifnone = RHASH_IFNONE(hash
if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
if (argc == 0) return Qnil;
args[0] = hash;
args[1] = argv[0];
return rb_funcallv(ifnone, id_yield, 2, args
}
return ifnone;
}
default = obj → obj Show source
设置默认值,即散列中不存在的键所返回的值。无法将默认设置为Proc
每个键查找时执行的默认值。
h = { "a" => 100, "b" => 200 }
h.default = "Go fish"
h["a"] #=> 100
h["z"] #=> "Go fish"
# This doesn't do what you might hope...
h.default = proc do |hash, key|
hash[key] = key + key
end
h[2] #=> #<Proc:0x401b3948@-:6>
h["cat"] #=> #<Proc:0x401b3948@-:6>
static VALUE
rb_hash_set_default(VALUE hash, VALUE ifnone)
{
rb_hash_modify_check(hash
SET_DEFAULT(hash, ifnone
return ifnone;
}
default_proc → anObject Show source
如果Hash::new
使用块调用,则返回该块,否则返回nil
。
h = Hash.new {|h,k| h[k] = k*k } #=> {}
p = h.default_proc #=> #<Proc:0x401b3d08@-:1>
a = [] #=> []
p.call(a, 2)
a #=> [nil, nil, 4]
static VALUE
rb_hash_default_proc(VALUE hash)
{
if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
return RHASH_IFNONE(hash
}
return Qnil;
}
default_proc = proc_obj or nil Show source
设置在每个失败的密钥查找中执行的默认proc。
h.default_proc = proc do |hash, key|
hash[key] = key + key
end
h[2] #=> 4
h["cat"] #=> "catcat"
VALUE
rb_hash_set_default_proc(VALUE hash, VALUE proc)
{
VALUE b;
rb_hash_modify_check(hash
if (NIL_P(proc)) {
SET_DEFAULT(hash, proc
return proc;
}
b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc"
if (NIL_P(b) || !rb_obj_is_proc(b)) {
rb_raise(rb_eTypeError,
"wrong default_proc type %s (expected Proc)",
rb_obj_classname(proc)
}
proc = b;
SET_PROC_DEFAULT(hash, proc
return proc;
}
delete(key) → value Show source
delete(key) {| key | block } → value
删除键值对并从键值等于键的hsh
返回值。如果找不到密钥,则返回nil
。如果给出可选的代码块
并且未找到密钥,则传入密钥并返回块
的结果。
h = { "a" => 100, "b" => 200 }
h.delete("a") #=> 100
h.delete("z") #=> nil
h.delete("z") { |el| "#{el} not found" } #=> "z not found"
static VALUE
rb_hash_delete_m(VALUE hash, VALUE key)
{
VALUE val;
rb_hash_modify_check(hash
val = rb_hash_delete_entry(hash, key
if (val != Qundef) {
return val;
}
else {
if (rb_block_given_p()) {
return rb_yield(key
}
else {
return Qnil;
}
}
}
delete_if {| key, value | block } → hsh Show source
delete_if → an_enumerator
删除从每一个键-值对HSH
针对块
的计算结果为true
。
如果没有给出块,则返回一个枚举器。
h = { "a" => 100, "b" => 200, "c" => 300 }
h.delete_if {|key, value| key >= "b" } #=> {"a"=>100}
VALUE
rb_hash_delete_if(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
rb_hash_modify_check(hash
if (RHASH(hash)->ntbl)
rb_hash_foreach(hash, delete_if_i, hash
return hash;
}
dig(key, ...) → object Show source
通过在每个步骤调用来提取由关键
对象序列指定的嵌套值dig
,nil
如果有任何中间步骤则返回nil
。
h = { foo: {bar: {baz: 1}}}
h.dig(:foo, :bar, :baz) #=> 1
h.dig(:foo, :zot, :xyz) #=> nil
g = { foo: [10, 11, 12] }
g.dig(:foo, 1) #=> 11
g.dig(:foo, 1, 0) #=> TypeError: Integer does not have #dig method
g.dig(:foo, :bar) #=> TypeError: no implicit conversion of Symbol into Integer
VALUE
rb_hash_dig(int argc, VALUE *argv, VALUE self)
{
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS
self = rb_hash_aref(self, *argv
if (!--argc) return self;
++argv;
return rb_obj_dig(argc, argv, self, Qnil
}
each {| key, value | block } → hsh Show source
each_pair {| key, value | block } → hsh
each → an_enumerator
each_pair → an_enumerator
为hsh中的
每个键调用一次块
,传递键值对作为参数。
如果没有给出块,则返回一个枚举器。
h = { "a" => 100, "b" => 200 }
h.each {|key, value| puts "#{key} is #{value}" }
produces:
a is 100
b is 200
static VALUE
rb_hash_each_pair(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
if (rb_block_arity() > 1)
rb_hash_foreach(hash, each_pair_i_fast, 0
else
rb_hash_foreach(hash, each_pair_i, 0
return hash;
}
each_key {| key | block } → hsh Show source
each_key → an_enumerator
为hsh中的
每个键调用一次块
,将该键作为参数传递。
如果没有给出块,则返回一个枚举器。
h = { "a" => 100, "b" => 200 }
h.each_key {|key| puts key }
produces:
a
b
static VALUE
rb_hash_each_key(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
rb_hash_foreach(hash, each_key_i, 0
return hash;
}
each_pair {| key, value | block } → hsh Show source
each_pair → an_enumerator
为hsh中的
每个键调用一次块
,传递键值对作为参数。
如果没有给出块,则返回一个枚举器。
h = { "a" => 100, "b" => 200 }
h.each {|key, value| puts "#{key} is #{value}" }
produces:
a is 100
b is 200
static VALUE
rb_hash_each_pair(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
if (rb_block_arity() > 1)
rb_hash_foreach(hash, each_pair_i_fast, 0
else
rb_hash_foreach(hash, each_pair_i, 0
return hash;
}
each_value {| value | block } → hsh Show source
each_value → an_enumerator
为hsh中的
每个键调用一次块
,并将该值作为参数传递。
如果没有给出块,则返回一个枚举器。
h = { "a" => 100, "b" => 200 }
h.each_value {|value| puts value }
produces:
100
200
static VALUE
rb_hash_each_value(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
rb_hash_foreach(hash, each_value_i, 0
return hash;
}
empty? → true or false Show source
如果hsh不
包含键值对,则返回true
。
{}.empty? #=> true
static VALUE
rb_hash_empty_p(VALUE hash)
{
return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
}
eql?(other) → true or false Show source
如果散列
和其他
散列
具有相同内容,则返回true
散列
值。不会比较每个哈希的顺序。
static VALUE
rb_hash_eql(VALUE hash1, VALUE hash2)
{
return hash_equal(hash1, hash2, TRUE
}
fetch(key , default ) → obj Show source
fetch(key) {| key | block } → obj
从给定密钥的散列中返回一个值。如果找不到密钥,则有以下几种选择:如果没有其他参数,则会引发KeyError
异常;如果给出了默认值
,那么将返回;如果指定了可选的代码块,那么将运行该代码块并返回其结果。
h = { "a" => 100, "b" => 200 }
h.fetch("a") #=> 100
h.fetch("z", "go fish") #=> "go fish"
h.fetch("z") { |el| "go fish, #{el}"} #=> "go fish, z"
以下示例显示如果未找到密钥并且未提供默认值,则会引发异常。
h = { "a" => 100, "b" => 200 }
h.fetch("z")
produces:
prog.rb:2:in `fetch': key not found (KeyError)
from prog.rb:2
static VALUE
rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
{
VALUE key;
st_data_t val;
long block_given;
rb_check_arity(argc, 1, 2
key = argv[0];
block_given = rb_block_given_p(
if (block_given && argc == 2) {
rb_warn("block supersedes default value argument"
}
if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
if (block_given) return rb_yield(key
if (argc == 1) {
VALUE desc = rb_protect(rb_inspect, key, 0
if (NIL_P(desc)) {
desc = rb_any_to_s(key
}
desc = rb_str_ellipsize(desc, 65
rb_raise(rb_eKeyError, "key not found: %"PRIsVALUE, desc
}
return argv[1];
}
return (VALUE)val;
}
fetch_values(key, ...) → array Show source
fetch_values(key, ...) { |key| block } → array
返回包含与给定键相关联的值的数组,KeyError
但当找不到其中一个键时也会返回。另见Hash#values_at
和Hash#fetch
。
h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
h.fetch_values("cow", "cat") #=> ["bovine", "feline"]
h.fetch_values("cow", "bird") # raises KeyError
h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"]
VALUE
rb_hash_fetch_values(int argc, VALUE *argv, VALUE hash)
{
VALUE result = rb_ary_new2(argc
long i;
for (i=0; i<argc; i++) {
rb_ary_push(result, rb_hash_fetch(hash, argv[i])
}
return result;
}
flatten → an_array Show source
flatten(level) → an_array
返回一个新的数组,该哈希是一维平坦化的。也就是说,对于数组中的每个键或值,将其元素提取到新数组中。与Array#flatten不同,此方法默认情况下不会以递归方式平坦化。可选的参数级别
决定了要展平的递归级别
。
a = {1=> "one", 2 => [2,"two"], 3 => "three"}
a.flatten # => [1, "one", 2, [2, "two"], 3, "three"]
a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
static VALUE
rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
{
VALUE ary;
if (argc) {
int level = NUM2INT(*argv
if (level == 0) return rb_hash_to_a(hash
ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2
rb_hash_foreach(hash, flatten_i, ary
if (level - 1 > 0) {
*argv = INT2FIX(level - 1
rb_funcallv(ary, id_flatten_bang, argc, argv
}
else if (level < 0) {
rb_funcallv(ary, id_flatten_bang, 0, 0
}
}
else {
ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2
rb_hash_foreach(hash, flatten_i, ary
}
return ary;
}
has_key?(key) → true or false Show source
返回true
给定的键是否存在于hsh中
。
h = { "a" => 100, "b" => 200 }
h.has_key?("a") #=> true
h.has_key?("z") #=> false
请注意,include?
并member?
使用不测试成员平等==
的做其他可枚举。
另请参阅Enumerable #include?
VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
if (!RHASH(hash)->ntbl)
return Qfalse;
if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
return Qtrue;
}
return Qfalse;
}
has_value?(value) → true or false Show source
返回true
给定值是否存在于hsh中的
某个键。
h = { "a" => 100, "b" => 200 }
h.value?(100) #=> true
h.value?(999) #=> false
static VALUE
rb_hash_has_value(VALUE hash, VALUE val)
{
VALUE data[2];
data[0] = Qfalse;
data[1] = val;
rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data
return data[0];
}
hash → integer Show source
计算此散列的散列码。两个具有相同内容的散列将具有相同的散列码(并将使用比较eql?
)。
另请参阅Object#hash。
static VALUE
rb_hash_hash(VALUE hash)
{
st_index_t size = RHASH_SIZE(hash
st_index_t hval = rb_hash_start(size
hval = rb_hash_uint(hval, (st_index_t)rb_hash_hash
if (size) {
rb_hash_foreach(hash, hash_i, (VALUE)&hval
}
hval = rb_hash_end(hval
return ST2FIX(hval
}
include?(key) → true or false Show source
返回true
给定的键是否存在于hsh中
。
h = { "a" => 100, "b" => 200 }
h.has_key?("a") #=> true
h.has_key?("z") #=> false
请注意,include?
并member?
使用不测试成员平等==
的做其他可枚举。
另请参阅Enumerable #include?
VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
if (!RHASH(hash)->ntbl)
return Qfalse;
if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
return Qtrue;
}
return Qfalse;
}
to_s → string Show source
inspect → string
以字符串形式返回此散列的内容。
h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
h.to_s #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
static VALUE
rb_hash_inspect(VALUE hash)
{
if (RHASH_EMPTY_P(hash))
return rb_usascii_str_new2("{}"
return rb_exec_recursive(inspect_hash, hash, 0
}
另外别名为:to_s
invert → new_hash Show source
返回通过使用hsh
的值作为键创建的新散列,并将键作为值创建。如果在hsh中
已经存在具有相同值的密钥,则使用定义的最后一个密钥,较早的值将被丢弃。
h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
h.invert #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
如果没有具有相同值的键,则#invert是合成的。
h = { a: 1, b: 3, c: 4 }
h.invert.invert == h #=> true
可以通过比较反转散列的大小来测试条件,即不具有相同值的键。
# no key with the same value
h = { a: 1, b: 3, c: 4 }
h.size == h.invert.size #=> true
# two (or more) keys has the same value
h = { a: 1, b: 3, c: 1 }
h.size == h.invert.size #=> false
static VALUE
rb_hash_invert(VALUE hash)
{
VALUE h = rb_hash_new(
rb_hash_foreach(hash, rb_hash_invert_i, h
return h;
}
keep_if {| key, value | block } → hsh Show source
keep_if → an_enumerator
删除从每一个键-值对HSH
为哪些块
评估为假。
如果没有给出块,则返回一个枚举器。
VALUE
rb_hash_keep_if(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
rb_hash_modify_check(hash
if (RHASH(hash)->ntbl)
rb_hash_foreach(hash, keep_if_i, hash
return hash;
}
key(value) → key Show source
返回给定值发生的关键。如果未找到该值,则返回nil
。
h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
h.key(200) #=> "b"
h.key(300) #=> "c"
h.key(999) #=> nil
static VALUE
rb_hash_key(VALUE hash, VALUE value)
{
VALUE args[2];
args[0] = value;
args[1] = Qnil;
rb_hash_foreach(hash, key_i, (VALUE)args
return args[1];
}
key?(key) → true or false Show source
返回true
给定的键是否存在于hsh中
。
h = { "a" => 100, "b" => 200 }
h.has_key?("a") #=> true
h.has_key?("z") #=> false
请注意,include?
并member?
使用不测试成员平等==
的做其他可枚举。
另请参阅Enumerable #include?
VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
if (!RHASH(hash)->ntbl)
return Qfalse;
if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
return Qtrue;
}
return Qfalse;
}
keys → array Show source
返回一个新数组,其中填充了该散列中的键。另见Hash#values
。
h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
h.keys #=> ["a", "b", "c", "d"]
VALUE
rb_hash_keys(VALUE hash)
{
VALUE keys;
st_index_t size = RHASH_SIZE(hash
keys = rb_ary_new_capa(size
if (size == 0) return keys;
if (ST_DATA_COMPATIBLE_P(VALUE)) {
st_table *table = RHASH(hash)->ntbl;
rb_gc_writebarrier_remember(keys
RARRAY_PTR_USE(keys, ptr, {
size = st_keys_check(table, ptr, size, Qundef
}
rb_ary_set_len(keys, size
}
else {
rb_hash_foreach(hash, keys_i, keys
}
return keys;
}
length → integer Show source
返回散列中的键值对的数量。
h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
h.length #=> 4
h.delete("a") #=> 200
h.length #=> 3
VALUE
rb_hash_size(VALUE hash)
{
return INT2FIX(RHASH_SIZE(hash)
}
member?(key) → true or false Show source
返回true
给定的键是否存在于hsh中
。
h = { "a" => 100, "b" => 200 }
h.has_key?("a") #=> true
h.has_key?("z") #=> false
请注意,include?
并member?
使用不测试成员平等==
的做其他可枚举。
另请参阅Enumerable #include?
VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
if (!RHASH(hash)->ntbl)
return Qfalse;
if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
return Qtrue;
}
return Qfalse;
}
merge(other_hash) → new_hash Show source
merge(other_hash){|key, oldval, newval| block} → new_hash
返回包含内容的新的哈希other_hash
和内容HSH
。如果未指定块,则具有重复键的条目的值将是other_hash的值
。否则,每个重复键的值都是通过用键调用块来确定的,它的值在hsh中
,值在other_hash中
。
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge(h2) #=> {"a"=>100, "b"=>254, "c"=>300}
h1.merge(h2){|key, oldval, newval| newval - oldval}
#=> {"a"=>100, "b"=>54, "c"=>300}
h1 #=> {"a"=>100, "b"=>200}
static VALUE
rb_hash_merge(VALUE hash1, VALUE hash2)
{
return rb_hash_update(rb_obj_dup(hash1), hash2
}
merge!(other_hash) → hsh Show source
merge!(other_hash){|key, oldval, newval| block} → hsh
将other_hash
的内容添加到hsh
。如果未指定块,则使用other_hash中
的值覆盖具有重复键的条目,否则每个重复键的值由通过键调用块确定,其值在hsh中
,值在other_hash中确定
。
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2) #=> {"a"=>100, "b"=>254, "c"=>300}
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2) { |key, v1, v2| v1 }
#=> {"a"=>100, "b"=>200, "c"=>300}
static VALUE
rb_hash_update(VALUE hash1, VALUE hash2)
{
rb_hash_modify(hash1
hash2 = to_hash(hash2
if (rb_block_given_p()) {
rb_hash_foreach(hash2, rb_hash_update_block_i, hash1
}
else {
rb_hash_foreach(hash2, rb_hash_update_i, hash1
}
return hash1;
}
rassoc(obj) → an_array or nil Show source
通过hash比较obj
和使用的值进行搜索==
。返回匹配的第一个键 - 值对(双元素数组)。另见Array#rassoc
。
a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
a.rassoc("two") #=> [2, "two"]
a.rassoc("four") #=> nil
VALUE
rb_hash_rassoc(VALUE hash, VALUE obj)
{
VALUE args[2];
args[0] = obj;
args[1] = Qnil;
rb_hash_foreach(hash, rassoc_i, (VALUE)args
return args[1];
}
rehash → hsh Show source
根据每个密钥的当前散列值重建散列。如果关键对象的值自插入后发生了更改,则此方法将重新索引hsh
。如果Hash#rehash
在迭代器遍历散列时调用,则迭代器RuntimeError
中将引发一个。
a = [ "a", "b" ]
c = [ "c", "d" ]
h = { a => 100, c => 300 }
h[a] #=> 100
a[0] = "z"
h[a] #=> nil
h.rehash #=> {["z", "b"]=>100, ["c", "d"]=>300}
h[a] #=> 100
VALUE
rb_hash_rehash(VALUE hash)
{
VALUE tmp;
st_table *tbl;
if (RHASH_ITER_LEV(hash) > 0) {
rb_raise(rb_eRuntimeError, "rehash during iteration"
}
rb_hash_modify_check(hash
if (!RHASH(hash)->ntbl)
return hash;
tmp = hash_alloc(0
tbl = st_init_table_with_size(RHASH(hash)->ntbl->type, RHASH(hash)->ntbl->num_entries
RHASH(tmp)->ntbl = tbl;
rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tbl
st_free_table(RHASH(hash)->ntbl
RHASH(hash)->ntbl = tbl;
RHASH(tmp)->ntbl = 0;
return hash;
}
reject {|key, value| block} → a_hash Show source
reject → an_enumerator
返回由该块返回false的条目组成的新散列。
如果没有给出块,则返回一个枚举器。
h = { "a" => 100, "b" => 200, "c" => 300 }
h.reject {|k,v| k < "b"} #=> {"b" => 200, "c" => 300}
h.reject {|k,v| v > 100} #=> {"a" => 100}
VALUE
rb_hash_reject(VALUE hash)
{
VALUE result;
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
if (RTEST(ruby_verbose)) {
VALUE klass;
if (HAS_EXTRA_STATES(hash, klass)) {
rb_warn("extra states are no longer copied: %+"PRIsVALUE, hash
}
}
result = rb_hash_new(
if (!RHASH_EMPTY_P(hash)) {
rb_hash_foreach(hash, reject_i, result
}
return result;
}
reject! {| key, value | block } → hsh or nil Show source
reject! → an_enumerator
等同于Hash#delete_if
,但如果没有更改,则返回nil
。
VALUE
rb_hash_reject_bang(VALUE hash)
{
st_index_t n;
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
rb_hash_modify(hash
n = RHASH_SIZE(hash
if (!n) return Qnil;
rb_hash_foreach(hash, delete_if_i, hash
if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
return hash;
}
replace(other_hash) → hsh Show source
用other_hash
的内容替换hsh
的内容。
h = { "a" => 100, "b" => 200 }
h.replace{ "c" => 300, "d" => 400 }) #=> {"c"=>300, "d"=>400}
static VALUE
rb_hash_replace(VALUE hash, VALUE hash2)
{
st_table *table2;
rb_hash_modify_check(hash
if (hash == hash2) return hash;
hash2 = to_hash(hash2
COPY_DEFAULT(hash, hash2
table2 = RHASH(hash2)->ntbl;
rb_hash_clear(hash
if (table2) hash_tbl(hash)->type = table2->type;
rb_hash_foreach(hash2, replace_i, hash
return hash;
}
select {|key, value| block} → a_hash Show source
select → an_enumerator
返回由该块返回true的条目组成的新散列。
如果没有给出块,则返回一个枚举器。
h = { "a" => 100, "b" => 200, "c" => 300 }
h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300}
h.select {|k,v| v < 200} #=> {"a" => 100}
VALUE
rb_hash_select(VALUE hash)
{
VALUE result;
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
result = rb_hash_new(
if (!RHASH_EMPTY_P(hash)) {
rb_hash_foreach(hash, select_i, result
}
return result;
}
select! {| key, value | block } → hsh or nil Show source
select! → an_enumerator
等同于Hash#keep_if
,但如果没有更改,则返回nil
。
VALUE
rb_hash_select_bang(VALUE hash)
{
st_index_t n;
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
rb_hash_modify_check(hash
if (!RHASH(hash)->ntbl)
return Qnil;
n = RHASH(hash)->ntbl->num_entries;
rb_hash_foreach(hash, keep_if_i, hash
if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
return hash;
}
shift → anArray or obj Show source
从hsh中
删除键值对,并将其作为两项数组[
键,值
]
或散列的默认值(如果散列为空)返回。
h = { 1 => "a", 2 => "b", 3 => "c" }
h.shift #=> [1, "a"]
h #=> {2=>"b", 3=>"c"}
static VALUE
rb_hash_shift(VALUE hash)
{
struct shift_var var;
rb_hash_modify_check(hash
if (RHASH(hash)->ntbl) {
var.key = Qundef;
if (RHASH_ITER_LEV(hash) == 0) {
if (st_shift(RHASH(hash)->ntbl, &var.key, &var.val)) {
return rb_assoc_new(var.key, var.val
}
}
else {
rb_hash_foreach(hash, shift_i_safe, (VALUE)&var
if (var.key != Qundef) {
rb_hash_delete_entry(hash, var.key
return rb_assoc_new(var.key, var.val
}
}
}
return rb_hash_default_value(hash, Qnil
}
size → integer Show source
返回散列中的键值对的数量。
h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
h.length #=> 4
h.delete("a") #=> 200
h.length #=> 3
VALUE
rb_hash_size(VALUE hash)
{
return INT2FIX(RHASH_SIZE(hash)
}
store(key, value) → value Show source
元素分配
将给定的值value
与由key
给定的关键字联系起来。
h = { "a" => 100, "b" => 200 }
h["a"] = 9
h["c"] = 4
h #=> {"a"=>9, "b"=>200, "c"=>4}
h.store("d", 42) #=> 42
h #=> {"a"=>9, "b"=>200, "c"=>4, "d"=>42}
key
在作为密钥使用时不应改变其值(unfrozen String
因为密钥将被复制并冻结)。
a = "a"
b = "b".freeze
h = { a => 100, b => 200 }
h.key(100).equal? a #=> false
h.key(200).equal? b #=> true
VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{
int iter_lev = RHASH_ITER_LEV(hash
st_table *tbl = RHASH(hash)->ntbl;
rb_hash_modify(hash
if (!tbl) {
if (iter_lev > 0) no_new_key(
tbl = hash_tbl(hash
}
if (tbl->type == &identhash || rb_obj_class(key) != rb_cString) {
RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val
}
else {
RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val
}
return val;
}
to_a → array Show source
将hsh
转换为[
键值
数组的嵌套数组]
。
h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
h.to_a #=> [["c", 300], ["a", 100], ["d", 400]]
static VALUE
rb_hash_to_a(VALUE hash)
{
VALUE ary;
ary = rb_ary_new_capa(RHASH_SIZE(hash)
rb_hash_foreach(hash, to_a_i, ary
OBJ_INFECT(ary, hash
return ary;
}
to_h → hsh or new_hash Show source
返回self
。如果在哈希的子类上调用,则将接收器转换为哈希对象。
static VALUE
rb_hash_to_h(VALUE hash)
{
if (rb_obj_class(hash) != rb_cHash) {
const VALUE flags = RBASIC(hash)->flags;
hash = hash_dup(hash, rb_cHash, flags & HASH_PROC_DEFAULT
}
return hash;
}
to_hash → hsh Show source
返回self
。
static VALUE
rb_hash_to_hash(VALUE hash)
{
return hash;
}
to_proc() Show source
static VALUE
rb_hash_to_proc(VALUE hash)
{
return rb_func_proc_new(hash_proc_call, hash
}
to_s()
Alias for: inspect
transform_values {|value| block } → hsh Show source
transform_values → an_enumerator
为每个值返回一次运行块的结果。此方法不会更改密钥。
h = { a: 1, b: 2, c: 3 }
h.transform_values {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
h.transform_values(&:to_s) #=> { a: "1", b: "2", c: "3" }
h.transform_values.with_index {|v, i| "#{v}.#{i}" }
#=> { a: "1.0", b: "2.1", c: "3.2" }
如果没有给出块,则返回一个枚举器。
static VALUE
rb_hash_transform_values(VALUE hash)
{
VALUE result;
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
result = rb_hash_new(
if (!RHASH_EMPTY_P(hash)) {
rb_hash_foreach(hash, transform_values_i, result
}
return result;
}
transform_values! {|value| block } → hsh Show source
transform_values! → an_enumerator
为每个值返回一次运行块的结果。此方法不会更改密钥。
h = { a: 1, b: 2, c: 3 }
h.transform_values! {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
h.transform_values!(&:to_s) #=> { a: "1", b: "2", c: "3" }
h.transform_values!.with_index {|v, i| "#{v}.#{i}" }
#=> { a: "1.0", b: "2.1", c: "3.2" }
如果没有给出块,则返回一个枚举器。
static VALUE
rb_hash_transform_values_bang(VALUE hash)
{
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size
rb_hash_modify_check(hash
if (RHASH(hash)->ntbl)
rb_hash_foreach(hash, transform_values_i, hash
return hash;
}
update(other_hash) → hsh Show source
update(other_hash){|key, oldval, newval| block} → hsh
将other_hash
的内容添加到hsh
。如果未指定块,则使用other_hash中
的值覆盖具有重复键的条目,否则每个重复键的值由通过键调用块确定,其值在hsh中
,值在other_hash中确定
。
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2) #=> {"a"=>100, "b"=>254, "c"=>300}
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge!(h2) { |key, v1, v2| v1 }
#=> {"a"=>100, "b"=>200, "c"=>300}
static VALUE
rb_hash_update(VALUE hash1, VALUE hash2)
{
rb_hash_modify(hash1
hash2 = to_hash(hash2
if (rb_block_given_p()) {
rb_hash_foreach(hash2, rb_hash_update_block_i, hash1
}
else {
rb_hash_foreach(hash2, rb_hash_update_i, hash1
}
return hash1;
}
value?(value) → true or false Show source
返回true
给定值是否存在于hsh中的
某个键。
h = { "a" => 100, "b" => 200 }
h.value?(100) #=> true
h.value?(999) #=> false
static VALUE
rb_hash_has_value(VALUE hash, VALUE val)
{
VALUE data[2];
data[0] = Qfalse;
data[1] = val;
rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data
return data[0];
}
values → array Show source
用hsh
的值返回一个新的数组。另见Hash#keys
。
h = { "a" => 100, "b" => 200, "c" => 300 }
h.values #=> [100, 200, 300]
VALUE
rb_hash_values(VALUE hash)
{
VALUE values;
st_index_t size = RHASH_SIZE(hash
values = rb_ary_new_capa(size
if (size == 0) return values;
if (ST_DATA_COMPATIBLE_P(VALUE)) {
st_table *table = RHASH(hash)->ntbl;
rb_gc_writebarrier_remember(values
RARRAY_PTR_USE(values, ptr, {
size = st_values_check(table, ptr, size, Qundef
}
rb_ary_set_len(values, size
}
else {
rb_hash_foreach(hash, values_i, values
}
return values;
}
values_at(key, ...) → array Show source
返回包含与给定键相关的值的数组。另见Hash.select
。
h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
h.values_at("cow", "cat") #=> ["bovine", "feline"]
VALUE
rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
{
VALUE result = rb_ary_new2(argc
long i;
for (i=0; i<argc; i++) {
rb_ary_push(result, rb_hash_aref(hash, argv[i])
}
return result;
}