非常教程

Ruby 2.4参考手册

Hash

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?

如果重写hasheql?方法以提供有意义的行为,用户定义的类可以用作散列键。默认情况下,单独的实例引用单独的散列键。

典型的实现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::newHash#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

通过在每个步骤调用来提取由关键对象序列指定的嵌套值dignil如果有任何中间步骤则返回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_atHash#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;
}
Hash
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct