Spec-Zone.ru › Ruby 2.3

класс Hash

Родитель:
Объект
Включенные модули:
Enumerable

A Хэш — это структура данных, подобная словарю, содержащая уникальные ключи и их значения. Также называемые ассоциативными массивами, они похожи на массивы, но вместо целых чисел в качестве индексов Хэш использует значения любого типа.

Хэши перечисляют свои значения в том порядке, в котором соответствующие ключи были вставлены.

A Хэш можно легко создать, используя его неявную форму:

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

A Хэш также можно создать с помощью метода ::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 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 Показать исходный код
Hash[ [ [key, value], ... ] ] → new_hash
Hash[ object ] → new_hash
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);
    for (i=0; i<argc; i+=2) {
        rb_hash_aset(hash, argv[i], argv[i + 1]);
    }

    return 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}
new → new_hash Показать исходный код
new(obj) → new_hash
new {|hash, key| block } → new_hash
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();
        default_proc_arity_check(ifnone);
        RHASH_SET_IFNONE(hash, ifnone);
        FL_SET(hash, HASH_PROC_DEFAULT);
    }
    else {
        rb_check_arity(argc, 0, 1);
        ifnone = argc == 0 ? Qnil : argv[0];
        RHASH_SET_IFNONE(hash, ifnone);
    }

    return 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"]
try_convert(obj) → hash or nil Показать исходный код
static VALUE
rb_hash_s_try_convert(VALUE dummy, VALUE hash)
{
    return rb_check_hash_type(hash);
}

Попытаться преобразовать obj в хэш, используя метод #to_hash. Возвращает преобразованный хэш или nil, если obj не может быть преобразован по какой-либо причине.

Hash.try_convert({1=>2})   # => {1=>2}
Hash.try_convert("1=>2")   # => nil

Публичные методы экземпляра

hash < other → true or false Show source
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);
}

Возвращает true если hash является подмножеством other.

h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 < h2    #=> true
h2 < h1    #=> false
h1 < h1    #=> false
hash <= other → true or false Show source
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);
}

Возвращает true если hash является подмножеством other или равен other.

h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 <= h2   #=> true
h2 <= h1   #=> false
h1 <= h1   #=> true
hsh == other_hash → true or false Show source
static VALUE
rb_hash_equal(VALUE hash1, VALUE hash2)
{
    return hash_equal(hash1, hash2, FALSE);
}

Равенство—Два хэша равны, если каждый из них содержит одинаковое количество ключей и если каждая пара ключ-значение равна (в соответствии с 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
hash > other → true or false Show source
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);
}

Возвращает true если other является подмножеством hash.

h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 > h2    #=> false
h2 > h1    #=> true
h1 > h1    #=> false
hash >= other → true or false Show source
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);
}

Возвращает true если other является подмножеством hash или равен hash.

h1 = {a:1, b:2}
h2 = {a:1, b:2, c:3}
h1 >= h2   #=> false
h2 >= h1   #=> true
h1 >= h1   #=> true
hsh[key] → value Show source
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;
}

Ссылка на элемент—Извлекает объект value, соответствующий объекту key. Если не найден, возвращает значение по умолчанию (см. Hash::new для подробностей).

h = { "a" => 100, "b" => 200 }
h["a"]   #=> 100
h["c"]   #=> nil
hsh[key] = value → value Show source
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;
}

Присваивание элемента

Связывает значение, заданное 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
any? [{ |(key, value)| block }] → true or false Show source
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;
}

См. также Enumerable#any?

assoc(obj) → an_array or nil Show source
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];
}

Ищет в хэше, сравнивая obj с ключом, используя ==. Возвращает пару ключ-значение (массив из двух элементов) или nil, если совпадение не найдено. См. Array#assoc.

h = {"colors"  => ["red", "blue", "green"],
     "letters" => ["a", "b", "c" ]}
h.assoc("letters")  #=> ["letters", ["a", "b", "c"]]
h.assoc("foo")      #=> nil
clear → hsh Show source
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;
}

Удаляет все пары ключ-значение из hsh.

h = { "a" => 100, "b" => 200 }   #=> {"a"=>100, "b"=>200}
h.clear                          #=> {}
compare_by_identity → hsh Show source
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;
}

Заставляет 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.
compare_by_identity? → true or false Show source
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;
}

Возвращает true если hsh будет сравнивать свои ключи по их идентичности. Также см. Hash#compare_by_identity.

default(key=nil) → obj Show source
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;
}

Возвращает значение по умолчанию, значение, которое возвращалось бы hsh, если бы key не существовал в hsh. См. также Hash::new и Hash#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
default = obj → obj Show source
static VALUE
rb_hash_set_default(VALUE hash, VALUE ifnone)
{
    rb_hash_modify_check(hash);
    RHASH_SET_IFNONE(hash, ifnone);
    FL_UNSET(hash, HASH_PROC_DEFAULT);
    return ifnone;
}

Устанавливает значение по умолчанию, значение, возвращаемое для ключа, который не существует в хэше. Невозможно установить значение по умолчанию в 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>
default_proc → anObject Show source
static VALUE
rb_hash_default_proc(VALUE hash)
{
    if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
        return RHASH_IFNONE(hash);
    }
    return Qnil;
}

Если 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]
default_proc = proc_obj or nil Show source
VALUE
rb_hash_set_default_proc(VALUE hash, VALUE proc)
{
    VALUE b;

    rb_hash_modify_check(hash);
    if (NIL_P(proc)) {
        FL_UNSET(hash, HASH_PROC_DEFAULT);
        RHASH_SET_IFNONE(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;
    default_proc_arity_check(proc);
    RHASH_SET_IFNONE(hash, proc);
    FL_SET(hash, HASH_PROC_DEFAULT);
    return proc;
}

Устанавливает процедуру по умолчанию, которая будет выполняться при каждом неудачном поиске ключа.

h.default_proc = proc do |hash, key|
  hash[key] = key + key
end
h[2]       #=> 4
h["cat"]   #=> "catcat"
delete(key) → value Show source
delete(key) {| key | block } → value
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;
        }
    }
}

Удаляет пару ключ-значение и возвращает значение из hsh, ключ которого равен key. Если ключ не найден, возвращает nil. Если задан необязательный блок кода и ключ не найден, передайте ключ и верните результат block.

h = { "a" => 100, "b" => 200 }
h.delete("a")                              #=> 100
h.delete("z")                              #=> nil
h.delete("z") { |el| "#{el} not found" }   #=> "z not found"
delete_if {| key, value | block } → hsh Show source
delete_if → an_enumerator
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;
}

Удаляет каждую пару ключ-значение из hsh, для которой block вычисляет в true.

Если блок не задан, вместо этого возвращается перечислитель.

h = { "a" => 100, "b" => 200, "c" => 300 }
h.delete_if {|key, value| key >= "b" }   #=> {"a"=>100}
dig(key, ...) → object Show source
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);
}

Извлекает вложенное значение, указанное последовательностью объектов key, вызывая 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: Fixnum does not have #dig method
g.dig(:foo, :bar)           #=> TypeError: no implicit conversion of Symbol into Integer
each {| key, value | block } → hsh Show source
each_pair {| key, value | block } → hsh
each → an_enumerator
each_pair → an_enumerator
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;
}

Вызывает block один раз для каждого ключа в hsh, передавая пару ключ-значение в качестве параметров.

Если блок не задан, вместо этого возвращается перечислитель.

h = { "a" => 100, "b" => 200 }
h.each {|key, value| puts "#{key} is #{value}" }

выводит:

a is 100
b is 200
each_key {| key | block } → hsh Show source
each_key → an_enumerator
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;
}

Вызывает block один раз для каждого ключа в hsh, передавая ключ в качестве параметра.

Если блок не задан, вместо этого возвращается перечислитель.

h = { "a" => 100, "b" => 200 }
h.each_key {|key| puts key }

выводит:

a
b
each_pair {| key, value | block } → hsh Показать исходный код
each_pair → an_enumerator
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;
}

Вызывает block один раз для каждого ключа в hsh, передавая пару ключ-значение в качестве параметров.

Если блок не задан, вместо этого возвращается перечислитель.

h = { "a" => 100, "b" => 200 }
h.each {|key, value| puts "#{key} is #{value}" }

результат:

a is 100
b is 200
each_value {| value | block } → hsh Показать исходный код
each_value → an_enumerator
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;
}

Вызывает block один раз для каждого ключа в hsh, передавая значение в качестве параметра.

Если блок не задан, вместо этого возвращается перечислитель.

h = { "a" => 100, "b" => 200 }
h.each_value {|value| puts value }

результат:

100
200
empty? → true or false Показать исходный код
static VALUE
rb_hash_empty_p(VALUE hash)
{
    return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
}

Возвращает true если hsh не содержит пар ключ-значение.

{}.empty?   #=> true
eql?(other) → true or false Показать исходный код
static VALUE
rb_hash_eql(VALUE hash1, VALUE hash2)
{
    return hash_equal(hash1, hash2, TRUE);
}

Возвращает true если hash и other являются хэшами с одинаковым содержимым. Порядок элементов хэшей не сравнивается.

fetch(key [, default] ) → obj Показать исходный код
fetch(key) {| key | block } → obj
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;
}

Возвращает значение из хэша для заданного ключа. Если ключ не найден, есть несколько вариантов: без других аргументов, будет выброшено исключение KeyError; если задано значение default, то оно будет возвращено; если указан необязательный блок кода, то он будет выполнен и его результат будет возвращен.

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

результат:

prog.rb:2:in `fetch': key not found (KeyError)
 from prog.rb:2
fetch_values(key, ...) → array Показать исходный код
fetch_values(key, ...) { |key| block } → array
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;
}

Возвращает массив, содержащий значения, связанные с заданными ключами, но также вызывает 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"]
flatten → an_array Показать исходный код
flatten(level) → an_array
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_funcall2(ary, id_flatten_bang, argc, argv);
        }
        else if (level < 0) {
            rb_funcall2(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;
}

Возвращает новый массив, являющийся одномерным сглаживанием этого хэша. То есть для каждого ключа или значения, являющегося массивом, извлекает его элементы в новый массив. В отличие от Array#flatten, этот метод не сглаживает рекурсивно по умолчанию. Необязательный аргумент level определяет уровень рекурсии для сглаживания.

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"]
has_key?(key) → true or false Показать исходный код
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;
}

Возвращает true если заданный ключ присутствует в hsh.

h = { "a" => 100, "b" => 200 }
h.has_key?("a")   #=> true
h.has_key?("z")   #=> false

Обратите внимание, что include? и member? не проверяют равенство элементов с помощью ==, как другие перечисляемые.

См. также Enumerable#include?

has_value?(value) → true or 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];
}

Возвращает true если заданное значение присутствует для некоторого ключа в hsh.

h = { "a" => 100, "b" => 200 }
h.has_value?(100)   #=> true
h.has_value?(999)   #=> false
hash → fixnum Показать исходный код
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 INT2FIX(hval);
}

Вычисляет хэш-код для этого хэша. Два хэша с одинаковым содержимым будут иметь одинаковый хэш-код (и будут сравниваться с помощью eql?).

См. также Object#hash.

include?(key) → true or false Показать исходный код
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;
}

Возвращает true если заданный ключ присутствует в hsh.

h = { "a" => 100, "b" => 200 }
h.has_key?("a")   #=> true
h.has_key?("z")   #=> false

Обратите внимание, что include? и member? не проверяют равенство элементов с помощью ==, как другие перечисляемые.

См. также Enumerable#include?

to_s → string Показать исходный код
inspect → string
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);
}

Возвращает содержимое этого хэша в виде строки.

h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
h.to_s   #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
Также известен как: to_s
invert → new_hash Показать исходный код
static VALUE
rb_hash_invert(VALUE hash)
{
    VALUE h = rb_hash_new();

    rb_hash_foreach(hash, rb_hash_invert_i, h);
    return h;
}

Возвращает новый хэш, созданный с использованием значений hsh в качестве ключей, а ключей — в качестве значений. Если ключ с тем же значением уже существует в hsh, то будет использовано последнее определенное значение, предыдущие значения будут отброшены.

h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
h.invert   #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
keep_if {| key, value | block } → hsh Показать исходный код
keep_if → an_enumerator
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;
}

Удаляет все пары ключ-значение из hsh, для которых block вычисляет значение false.

Если блок не задан, вместо этого возвращается перечислитель.

key(value) → key Показать исходный код
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];
}

Возвращает ключ вхождения заданного значения. Если значение не найдено, возвращает nil.

h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
h.key(200)   #=> "b"
h.key(300)   #=> "c"
h.key(999)   #=> nil
key?(key) → true or false Показать исходный код
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;
}

Возвращает true если заданный ключ присутствует в hsh.

h = { "a" => 100, "b" => 200 }
h.has_key?("a")   #=> true
h.has_key?("z")   #=> false

Обратите внимание, что include? и member? не проверяют равенство элементов с помощью ==, как другие перечисляемые.

См. также Enumerable#include?

keys → array Показать исходный код
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;
}

Возвращает новый массив, заполненный ключами из этого хэша. См. также Hash#values.

h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
h.keys   #=> ["a", "b", "c", "d"]
length → fixnum Показать исходный код
VALUE
rb_hash_size(VALUE hash)
{
    return INT2FIX(RHASH_SIZE(hash));
}

Возвращает количество пар ключ-значение в хэше.

h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
h.length        #=> 4
h.delete("a")   #=> 200
h.length        #=> 3
member?(key) → true or false Показать исходный код
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;
}

Возвращает true если заданный ключ присутствует в hsh.

h = { "a" => 100, "b" => 200 }
h.has_key?("a")   #=> true
h.has_key?("z")   #=> false

Обратите внимание, что include? и member? не проверяют равенство элементов с помощью ==, как другие перечисляемые.

См. также Enumerable#include?

merge(other_hash) → new_hash Показать исходный код
merge(other_hash){|key, oldval, newval| block} → new_hash
static VALUE
rb_hash_merge(VALUE hash1, VALUE hash2)
{
    return rb_hash_update(rb_obj_dup(hash1), hash2);
}

Возвращает новый хэш, содержащий содержимое 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}
merge!(other_hash) → hsh Показать исходный код
merge!(other_hash){|key, oldval, newval| block} → hsh
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;
}

Добавляет содержимое 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}
rassoc(obj) → an_array or 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];
}

Ищет в хэше, сравнивая obj со значением, используя ==. Возвращает первую пару ключ-значение (массив из двух элементов), которая совпадает. См. также Array#rassoc.

a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
a.rassoc("two")    #=> [2, "two"]
a.rassoc("four")   #=> nil
rehash → hsh Показать исходный код
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;
}

Перестраивает хэш на основе текущих значений хэша для каждого ключа. Если значения объектов ключей изменились с момента их вставки, этот метод переиндексирует 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
reject {|key, value| block} → a_hash Показать исходный код
reject → an_enumerator
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;
}

Возвращает новый хэш, состоящий из записей, для которых блок возвращает 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}
reject! {| key, value | block } → hsh or nil Показать исходный код
reject! → an_enumerator
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;
}

Эквивалентно Hash#delete_if, но возвращает nil если изменений не было.

replace(other_hash) → hsh Показать исходный код
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);

    RHASH_SET_IFNONE(hash, RHASH_IFNONE(hash2));
    if (FL_TEST(hash2, HASH_PROC_DEFAULT))
        FL_SET(hash, HASH_PROC_DEFAULT);
    else
        FL_UNSET(hash, HASH_PROC_DEFAULT);

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

Заменяет содержимое hsh содержимым other_hash.

h = { "a" => 100, "b" => 200 }
h.replace({ "c" => 300, "d" => 400 })   #=> {"c"=>300, "d"=>400}
select {|key, value| block} → a_hash Показать исходный код
select → an_enumerator
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;
}

Возвращает новый хэш, состоящий из записей, для которых блок возвращает 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}
select! {| key, value | block } → hsh or nil Показать исходный код
select! → an_enumerator
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;
}

Эквивалентно Hash#keep_if, но возвращает nil если изменений не было.

shift → anArray or obj Показать исходный код
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);
}

Удаляет пару ключ-значение из hsh и возвращает ее как массив из двух элементов [ ключ, значение ], или значение по умолчанию хэша, если хэш пуст.

h = { 1 => "a", 2 => "b", 3 => "c" }
h.shift   #=> [1, "a"]
h         #=> {2=>"b", 3=>"c"}
size → fixnum Показать исходный код
VALUE
rb_hash_size(VALUE hash)
{
    return INT2FIX(RHASH_SIZE(hash));
}

Возвращает количество пар ключ-значение в хэше.

h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
h.length        #=> 4
h.delete("a")   #=> 200
h.length        #=> 3
store(key, value) → value Показать исходный код
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;
}

Присваивание элемента

Связывает значение, заданное 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
to_a → array Показать исходный код
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;
}

Преобразует hsh в вложенный массив из [ массивов ключ, значение ].

h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
h.to_a   #=> [["c", 300], ["a", 100], ["d", 400]]
to_h → hsh or new_hash Показать исходный код
static VALUE
rb_hash_to_h(VALUE hash)
{
    if (rb_obj_class(hash) != rb_cHash) {
        VALUE ret = rb_hash_new();
        if (!RHASH_EMPTY_P(hash))
            RHASH(ret)->ntbl = st_copy(RHASH(hash)->ntbl);
        if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
            FL_SET(ret, HASH_PROC_DEFAULT);
        }
        RHASH_SET_IFNONE(ret, RHASH_IFNONE(hash));
        return ret;
    }
    return hash;
}

Возвращает self. Если вызов осуществляется на подклассе Hash, конвертирует получателя в объект Hash.

to_hash → hsh Показать исходный код
static VALUE
rb_hash_to_hash(VALUE hash)
{
    return hash;
}

Возвращает self.

to_proc() Показать исходный код
static VALUE
rb_hash_to_proc(VALUE hash)
{
    return rb_func_proc_new(hash_proc_call, hash);
}
to_s()
Псевдоним для: inspect
update(other_hash) → hsh Показать исходный код
update(other_hash){|key, oldval, newval| block} → hsh
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;
}

Добавляет содержимое 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}
value?(value) → true or 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];
}

Возвращает true если заданное значение присутствует для некоторого ключа в hsh.

h = { "a" => 100, "b" => 200 }
h.has_value?(100)   #=> true
h.has_value?(999)   #=> false
values → array Показать исходный код
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;
}

Возвращает новый массив, заполненный значениями из hsh. См. также Hash#keys.

h = { "a" => 100, "b" => 200, "c" => 300 }
h.values   #=> [100, 200, 300]
values_at(key, ...) → array Показать исходный код
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.select.

h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
h.values_at("cow", "cat")  #=> ["bovine", "feline"]

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API