Class: Hash

Inherits:
Object show all
Includes:
Enumerable
Defined in:
gems/carbuncle-doc-ext/mrblib/hash.rb,
mruby/src/hash.c,
mruby/mrblib/hash.rb,
mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb

Overview

Hash

ISO 15.2.13

Constant Summary

Constants included from Enumerable

Enumerable::NONE

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

__update_hash, #all?, #any?, #chain, #collect, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_slice, #each_with_index, #each_with_object, #entries, #filter_map, #find_all, #find_index, #first, #flat_map, #grep, #group_by, #hash, #inject, #lazy, #max, #max_by, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reverse_each, #sort, #sort_by, #sum, #take, #take_while, #tally, #uniq, #zip

Constructor Details

#newObject #new(obj) ⇒ Object #new {|hash, key| ... } ⇒ Object

Returns a new, empty hash. If this hash is subsequently accessed by a key that doesn’t correspond to a hash entry, the value returned depends on the style of new used to create the hash. In the first form, the access returns nil. If obj is specified, this single object will be used for all default values. If a block is specified, it will be called with the hash object and the key, and should return the default value. It is the block’s responsibility to store the value in the hash if required.

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

Overloads:



1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
# File 'mruby/src/hash.c', line 1287

static mrb_value
mrb_hash_init(mrb_state *mrb, mrb_value hash)
{
  mrb_value block, ifnone;
  mrb_bool ifnone_p;

  ifnone = mrb_nil_value();
  mrb_get_args(mrb, "&|o?", &block, &ifnone, &ifnone_p);
  hash_modify(mrb, hash);
  if (!mrb_nil_p(block)) {
    if (ifnone_p) {
      mrb_argnum_error(mrb, 1, 0, 0);
    }
    RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
    ifnone = block;
  }
  if (!mrb_nil_p(ifnone)) {
    RHASH(hash)->flags |= MRB_HASH_DEFAULT;
    mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
  }
  return hash;
}

Class Method Details

.[](*object) ⇒ Object

call-seq:

Hash[ key, value, ... ] -> new_hash
Hash[ [ [key, value], ... ] ] -> new_hash
Hash[ object ] -> new_hash

Creates a new hash populated with the given objects.

Similar to the literal ‘{ key => value, … }`. In the first form, keys and values occur in pairs, so there must be an even number of arguments.

The second and third form take a single argument which is either an array of key-value pairs or an object convertible to a hash.

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}


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 26

def self.[](*object)
  length = object.length
  if length == 1
    o = object[0]
    if Hash === o
      h = self.new
      o.each { |k, v| h[k] = v }
      return h
    elsif o.respond_to?(:to_a)
      h = self.new
      o.to_a.each do |i|
        raise ArgumentError, "wrong element type #{i.class} (expected array)" unless i.respond_to?(:to_a)
        k, v = nil
        case i.size
        when 2
          k = i[0]
          v = i[1]
        when 1
          k = i[0]
        else
          raise ArgumentError, "invalid number of elements (#{i.size} for 1..2)"
        end
        h[k] = v
      end
      return h
    end
  end
  unless length % 2 == 0
    raise ArgumentError, 'odd number of arguments for Hash'
  end
  h = self.new
  0.step(length - 2, 2) do |i|
    h[object[i]] = object[i + 1]
  end
  h
end

Instance Method Details

#<(hash) ⇒ Object

call-seq:

  hash < other -> true or false

Returns <code>true</code> if <i>hash</i> is subset of
<i>other</i>.

   h1 = {a:1, b:2}
   h2 = {a:1, b:2, c:3}
   h1 < h2    #=> true
   h2 < h1    #=> false
   h1 < h1    #=> false

Raises:



316
317
318
319
320
321
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 316

def <(hash)
  raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
  size < hash.size and all? {|key, val|
    hash.key?(key) and hash[key] == val
  }
end

#<=(hash) ⇒ Object

call-seq:

  hash <= other -> true or false

Returns <code>true</code> if <i>hash</i> is subset of
<i>other</i> or equals to <i>other</i>.

   h1 = {a:1, b:2}
   h2 = {a:1, b:2, c:3}
   h1 <= h2   #=> true
   h2 <= h1   #=> false
   h1 <= h1   #=> true

Raises:



336
337
338
339
340
341
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 336

def <=(hash)
  raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
  size <= hash.size and all? {|key, val|
    hash.key?(key) and hash[key] == val
  }
end

#==(hash) ⇒ Object

call-seq:

 hash == object -> true or false

Equality---Two hashes are equal if they each contain the same number
of keys and if each key-value pair is equal to (according to
<code>Object#==</code>) the corresponding elements in the other
hash.

ISO 15.2.13.4.1



22
23
24
25
26
27
28
29
30
31
32
33
# File 'mruby/mrblib/hash.rb', line 22

def ==(hash)
  return true if self.equal?(hash)
  unless Hash === hash
    return false
  end
  return false if self.size != hash.size
  self.each do |k,v|
    return false unless hash.key?(k)
    return false unless self[k] == hash[k]
  end
  return true
end

#>(hash) ⇒ Object

call-seq:

  hash > other -> true or false

Returns <code>true</code> if <i>other</i> is subset of
<i>hash</i>.

   h1 = {a:1, b:2}
   h2 = {a:1, b:2, c:3}
   h1 > h2    #=> false
   h2 > h1    #=> true
   h1 > h1    #=> false

Raises:



356
357
358
359
360
361
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 356

def >(hash)
  raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
  size > hash.size and hash.all? {|key, val|
    key?(key) and self[key] == val
  }
end

#>=(hash) ⇒ Object

call-seq:

  hash >= other -> true or false

Returns <code>true</code> if <i>other</i> is subset of
<i>hash</i> or equals to <i>hash</i>.

   h1 = {a:1, b:2}
   h2 = {a:1, b:2, c:3}
   h1 >= h2   #=> false
   h2 >= h1   #=> true
   h1 >= h1   #=> true

Raises:



376
377
378
379
380
381
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 376

def >=(hash)
  raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash
  size >= hash.size and hash.all? {|key, val|
    key?(key) and self[key] == val
  }
end

#[](key) ⇒ Object

Element Reference—Retrieves the value object corresponding to the key object. If not found, returns the default value (see Hash::new for details).

h = { "a" => 100, "b" => 200 }
h["a"]   #=> 100
h["c"]   #=> nil


1324
1325
1326
1327
1328
1329
1330
# File 'mruby/src/hash.c', line 1324

static mrb_value
mrb_hash_aget(mrb_state *mrb, mrb_value self)
{
  mrb_value key = mrb_get_arg1(mrb);

  return mrb_hash_get(mrb, self, key);
}

#[]=(key) ⇒ Object #store(key, value) ⇒ Object

Element Assignment—Associates the value given by value with the key given by key. key should not have its value changed while it is in use as a key (a String passed as a key will be duplicated and frozen).

h = { "a" => 100, "b" => 200 }
h["a"] = 9
h["c"] = 4
h   #=> {"a"=>9, "b"=>200, "c"=>4}


1560
1561
1562
1563
1564
1565
1566
1567
1568
# File 'mruby/src/hash.c', line 1560

static mrb_value
mrb_hash_aset(mrb_state *mrb, mrb_value self)
{
  mrb_value key, val;

  mrb_get_args(mrb, "oo", &key, &val);
  mrb_hash_set(mrb, self, key, val);
  return val;
}

#__deleteObject

core of 15.2.13.4.8



1481
1482
1483
1484
1485
1486
1487
# File 'mruby/src/hash.c', line 1481

static mrb_value
mrb_hash_delete(mrb_state *mrb, mrb_value self)
{
  mrb_value key = mrb_get_arg1(mrb);
  mrb->c->ci->mid = 0;
  return mrb_hash_delete_key(mrb, self, key);
}

#__mergeObject



1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
# File 'mruby/src/hash.c', line 1750

static mrb_value
mrb_hash_merge_m(mrb_state *mrb, mrb_value hash)
{
  mrb_int argc;
  mrb_value *argv;

  mrb_get_args(mrb, "*", &argv, &argc);
  while (argc--) {
    mrb_hash_merge(mrb, hash, *argv++);
  }
  return hash;
}

#_inspect(recur_list) ⇒ Object

internal method for Hash inspection



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'mruby/mrblib/hash.rb', line 199

def _inspect(recur_list)
  return "{}" if self.size == 0
  return "{...}" if recur_list[self.object_id]
  recur_list[self.object_id] = true
  ary=[]
  keys=self.keys
  vals=self.values
  size=keys.size
  i=0
  while i<size
    ary<<(keys[i]._inspect(recur_list) + "=>" + vals[i]._inspect(recur_list))
    i+=1
  end
  "{"+ary.join(", ")+"}"
end

#clearHash

Removes all key-value pairs from ‘hsh`.

h = { "a" => 100, "b" => 200 }   #=> {"a"=>100, "b"=>200}
h.clear                          #=> {}

Returns:



1533
1534
1535
1536
1537
1538
1539
# File 'mruby/src/hash.c', line 1533

MRB_API mrb_value
mrb_hash_clear(mrb_state *mrb, mrb_value hash)
{
  hash_modify(mrb, hash);
  h_clear(mrb, mrb_hash_ptr(hash));
  return hash;
}

#compactObject

call-seq:

hsh.compact     -> new_hsh

Returns a new hash with the nil values/key pairs removed

h = { a: 1, b: false, c: nil }
h.compact     #=> { a: 1, b: false }
h             #=> { a: 1, b: false, c: nil }


138
139
140
141
142
143
144
145
146
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 138

def compact
  h = {}
  self.keys.select{|k|
    self[k] != nil
  }.each {|k|
    h[k] = self[k]
  }
  h
end

#compact!Object

call-seq:

hsh.compact!    -> hsh

Removes all nil values from the hash. Returns the hash. Returns nil if the hash does not contain nil values.

h = { a: 1, b: false, c: nil }
h.compact!     #=> { a: 1, b: false }


115
116
117
118
119
120
121
122
123
124
125
126
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 115

def compact!
  keys = self.keys
  nk = keys.select{|k|
    self[k] != nil
  }
  return nil if (keys.size == nk.size)
  h = {}
  nk.each {|k|
    h[k] = self[k]
  }
  self.replace(h)
end

#default(key = nil) ⇒ Object

Returns the default value, the value that would be returned by hsh[key] if key did not exist in hsh. See also Hash::new and 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

Returns:



1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
# File 'mruby/src/hash.c', line 1354

static mrb_value
mrb_hash_default(mrb_state *mrb, mrb_value hash)
{
  mrb_value key;
  mrb_bool given;

  mrb_get_args(mrb, "|o?", &key, &given);
  if (MRB_RHASH_DEFAULT_P(hash)) {
    if (MRB_RHASH_PROCDEFAULT_P(hash)) {
      if (!given) return mrb_nil_value();
      return mrb_funcall_id(mrb, RHASH_PROCDEFAULT(hash), MRB_SYM(call), 2, hash, key);
    }
    else {
      return RHASH_IFNONE(hash);
    }
  }
  return mrb_nil_value();
}

#default=(obj) ⇒ Object

Sets the default value, the value returned for a key that does not exist in the hash. It is not possible to set the default to a Proc that will be executed on each key lookup.

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>

Returns:



1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
# File 'mruby/src/hash.c', line 1394

static mrb_value
mrb_hash_set_default(mrb_state *mrb, mrb_value hash)
{
  mrb_value ifnone = mrb_get_arg1(mrb);

  hash_modify(mrb, hash);
  mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
  RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
  if (!mrb_nil_p(ifnone)) {
    RHASH(hash)->flags |= MRB_HASH_DEFAULT;
  }
  else {
    RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
  }
  return ifnone;
}

#default_procObject

If Hash::new was invoked with a block, return that block, otherwise return 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]

Returns:



1426
1427
1428
1429
1430
1431
1432
1433
# File 'mruby/src/hash.c', line 1426

static mrb_value
mrb_hash_default_proc(mrb_state *mrb, mrb_value hash)
{
  if (MRB_RHASH_PROCDEFAULT_P(hash)) {
    return RHASH_PROCDEFAULT(hash);
  }
  return mrb_nil_value();
}

#default_proc=(proc_obj) ⇒ Proc

Sets the default proc to be executed on each key lookup.

h.default_proc = proc do |hash, key|
  hash[key] = key + key
end
h[2]       #=> 4
h["cat"]   #=> "catcat"

Returns:



1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
# File 'mruby/src/hash.c', line 1448

static mrb_value
mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
{
  mrb_value ifnone = mrb_get_arg1(mrb);

  hash_modify(mrb, hash);
  mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
  if (!mrb_nil_p(ifnone)) {
    RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
    RHASH(hash)->flags |= MRB_HASH_DEFAULT;
  }
  else {
    RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
    RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
  }

  return ifnone;
}

#delete(key, &block) ⇒ Object

call-seq:

hash.delete(key) -> value or nil
hash.delete(key) {|key| ... } -> object

Delete the element with the key key. Return the value of the element if key was found. Return nil if nothing was found. If a block is given, call the block with the value of the element.

ISO 15.2.13.4.8



67
68
69
70
71
72
# File 'mruby/mrblib/hash.rb', line 67

def delete(key, &block)
  if block && !self.has_key?(key)
    return block.call(key)
  end
  self.__delete(key)
end

#delete_if(&block) ⇒ Object

call-seq:

   hsh.delete_if {| key, value | block }  -> hsh
   hsh.delete_if                          -> an_enumerator

Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
evaluates to <code>true</code>.

If no block is given, an enumerator is returned instead.

   h = { "a" => 100, "b" => 200, "c" => 300 }
   h.delete_if {|key, value| key >= "b" }   #=> {"a"=>100}


204
205
206
207
208
209
210
211
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 204

def delete_if(&block)
  return to_enum :delete_if unless block

  self.each do |k, v|
    self.delete(k) if block.call(k, v)
  end
  self
end

#dig(idx, *args) ⇒ Object

call-seq:

hsh.dig(key,...)                 -> object

Extracts the nested value specified by the sequence of key objects by calling dig at each step, returning nil if any intermediate step is nil.



391
392
393
394
395
396
397
398
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 391

def dig(idx,*args)
  n = self[idx]
  if args.size > 0
    n&.dig(*args)
  else
    n
  end
end

#each(&block) ⇒ Object Also known as: each_pair

call-seq:

hsh.each      {| key, value | block } -> hsh
hsh.each_pair {| key, value | block } -> hsh
hsh.each                              -> an_enumerator
hsh.each_pair                         -> an_enumerator

Calls the given block for each element of self and pass the key and value of each element.

If no block is given, an enumerator is returned instead.

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

produces:

a is 100 b is 200

ISO 15.2.13.4.9



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'mruby/mrblib/hash.rb', line 95

def each(&block)
  return to_enum :each unless block

  keys = self.keys
  vals = self.values
  len = self.size
  i = 0
  while i < len
    block.call [keys[i], vals[i]]
    i += 1
  end
  self
end

#each_key(&block) ⇒ Object

call-seq:

hsh.each_key {| key | block } -> hsh
hsh.each_key                  -> an_enumerator

Calls the given block for each element of self and pass the key of each element.

If no block is given, an enumerator is returned instead.

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

produces:

a
b

ISO 15.2.13.4.10



128
129
130
131
132
133
# File 'mruby/mrblib/hash.rb', line 128

def each_key(&block)
  return to_enum :each_key unless block

  self.keys.each{|k| block.call(k)}
  self
end

#each_value(&block) ⇒ Object

call-seq:

hsh.each_value {| value | block } -> self
hsh.each_value                    -> an_enumerator

Calls the given block with each value; returns self:

If no block is given, an enumerator is returned instead.

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

produces:

100
200

ISO 15.2.13.4.11



153
154
155
156
157
158
# File 'mruby/mrblib/hash.rb', line 153

def each_value(&block)
  return to_enum :each_value unless block

  self.values.each{|v| block.call(v)}
  self
end

#empty?Boolean

Returns true if hsh contains no key-value pairs.

{}.empty?   #=> true

Returns:

  • (Boolean)


1613
1614
1615
1616
1617
# File 'mruby/src/hash.c', line 1613

static mrb_value
mrb_hash_empty_m(mrb_state *mrb, mrb_value self)
{
  return mrb_bool_value(mrb_hash_empty_p(mrb, self));
}

#eql?(hash) ⇒ Boolean

call-seq:

hash.eql? object -> true or false

Returns true if hash and other are both hashes with the same content compared by eql?.

Returns:

  • (Boolean)


42
43
44
45
46
47
48
49
50
51
52
53
# File 'mruby/mrblib/hash.rb', line 42

def eql?(hash)
  return true if self.equal?(hash)
  unless Hash === hash
    return false
  end
  return false if self.size != hash.size
  self.each do |k,v|
    return false unless hash.key?(k)
    return false unless self[k].eql?(hash[k])
  end
  return true
end

#except(*keys) ⇒ Hash

Returns a hash excluding the given keys and their values.

h = { a: 100, b: 200, c: 300 }
h.except(:a)          #=> {:b=>200, :c=>300}
h.except(:b, :c, :d)  #=> {:a=>100}

Returns:



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'mruby/mrbgems/mruby-hash-ext/src/hash-ext.c', line 83

static mrb_value
hash_except(mrb_state *mrb, mrb_value hash)
{
  const mrb_value *argv;
  mrb_value result;
  mrb_int argc, i;

  mrb_get_args(mrb, "*", &argv, &argc);
  result = mrb_hash_dup(mrb, hash);
  for (i = 0; i < argc; i++) {
    mrb_hash_delete_key(mrb, result, argv[i]);
  }
  return result;
}

#fetch(key, none = NONE, &block) ⇒ Object

call-seq:

   hsh.fetch(key [, default] )       -> obj
   hsh.fetch(key) {| key | block }   -> obj

Returns a value from the hash for the given key. If the key can't be
found, there are several options: With no other arguments, it will
raise an <code>KeyError</code> exception; if <i>default</i> is
given, then that will be returned; if the optional code block is
specified, then that will be run and its result returned.

   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"

The following example shows that an exception is raised if the key
is not found and a default value is not supplied.

   h = { "a" => 100, "b" => 200 }
   h.fetch("z")

<em>produces:</em>

   prog.rb:2:in 'fetch': key not found (KeyError)
    from prog.rb:2


176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 176

def fetch(key, none=NONE, &block)
  unless self.key?(key)
    if block
      block.call(key)
    elsif none != NONE
      none
    else
      raise KeyError, "Key not found: #{key.inspect}"
    end
  else
    self[key]
  end
end

#fetch_values(*keys, &block) ⇒ Object

call-seq:

hsh.fetch_values(key, ...)                 -> array
hsh.fetch_values(key, ...) { |key| block } -> array

Returns an array containing the values associated with the given keys but also raises KeyError when one of keys can’t be found. Also see Hash#values_at and 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"]


492
493
494
495
496
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 492

def fetch_values(*keys, &block)
  keys.map do |k|
    self.fetch(k, &block)
  end
end

#flatten(level = 1) ⇒ Object

call-seq:

   hash.flatten -> an_array
   hash.flatten(level) -> an_array

Returns a new array that is a one-dimensional flattening of this
hash. That is, for every key or value that is an array, extract
its elements into the new array. Unlike Array#flatten, this
method does not flatten recursively by default. The optional
<i>level</i> argument determines the level of recursion to 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"]


229
230
231
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 229

def flatten(level=1)
  self.to_a.flatten(level)
end

#has_key?Boolean

15.2.13.4.13

Returns:

  • (Boolean)


1693
1694
1695
1696
1697
1698
1699
1700
1701
# File 'mruby/src/hash.c', line 1693

static mrb_value
mrb_hash_has_key(mrb_state *mrb, mrb_value hash)
{
  mrb_value key = mrb_get_arg1(mrb);
  mrb_bool key_p;

  key_p = mrb_hash_key_p(mrb, hash, key);
  return mrb_bool_value(key_p);
}

#has_value?(value) ⇒ Boolean #value?(value) ⇒ Boolean

Returns true if the given value is present for some key in hsh.

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

Overloads:

  • #has_value?(value) ⇒ Boolean

    Returns:

    • (Boolean)
  • #value?(value) ⇒ Boolean

    Returns:

    • (Boolean)


1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
# File 'mruby/src/hash.c', line 1718

static mrb_value
mrb_hash_has_value(mrb_state *mrb, mrb_value hash)
{
  mrb_value val = mrb_get_arg1(mrb);
  struct RHash *h = mrb_hash_ptr(hash);
  h_each(h, entry, {
    h_check_modified(mrb, h, {
      if (mrb_equal(mrb, val, entry->val)) return mrb_true_value();
    });
  });
  return mrb_false_value();
}

#include?Boolean

15.2.13.4.15

Returns:

  • (Boolean)


1693
1694
1695
1696
1697
1698
1699
1700
1701
# File 'mruby/src/hash.c', line 1693

static mrb_value
mrb_hash_has_key(mrb_state *mrb, mrb_value hash)
{
  mrb_value key = mrb_get_arg1(mrb);
  mrb_bool key_p;

  key_p = mrb_hash_key_p(mrb, hash, key);
  return mrb_bool_value(key_p);
}

#initialize_copyObject

15.2.13.4.17



1191
1192
1193
1194
1195
1196
1197
1198
1199
# File 'mruby/src/hash.c', line 1191

static mrb_value
mrb_hash_init_copy(mrb_state *mrb, mrb_value self)
{
  mrb_value orig;
  mrb_get_args(mrb, "H", &orig);
  hash_modify(mrb, self);
  if (mrb_hash_ptr(self) != mrb_hash_ptr(orig)) hash_replace(mrb, self, orig);
  return self;
}

#inspectObject Also known as: to_s

Return the contents of this hash as a string.



217
218
219
# File 'mruby/mrblib/hash.rb', line 217

def inspect
  self._inspect({})
end

#invertObject

call-seq:

   hsh.invert -> new_hash

Returns a new hash created by using <i>hsh</i>'s values as keys, and
the keys as values.

   h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
   h.invert   #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}


244
245
246
247
248
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 244

def invert
  h = self.class.new
  self.each {|k, v| h[v] = k }
  h
end

#keep_if(&block) ⇒ Object

call-seq:

   hsh.keep_if {| key, value | block }  -> hsh
   hsh.keep_if                          -> an_enumerator

Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
evaluates to false.

If no block is given, an enumerator is returned instead.


261
262
263
264
265
266
267
268
269
270
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 261

def keep_if(&block)
  return to_enum :keep_if unless block

  self.each do |k, v|
    unless block.call([k, v])
      self.delete(k)
    end
  end
  self
end

#key(val) ⇒ Object

call-seq:

   hsh.key(value)    -> key

Returns the key of an occurrence of a given value. If the value is
not found, returns <code>nil</code>.

   h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
   h.key(200)   #=> "b"
   h.key(300)   #=> "c"
   h.key(999)   #=> nil


285
286
287
288
289
290
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 285

def key(val)
  self.each do |k, v|
    return k if v == val
  end
  nil
end

#key?Boolean

15.2.13.4.18

Returns:

  • (Boolean)


1693
1694
1695
1696
1697
1698
1699
1700
1701
# File 'mruby/src/hash.c', line 1693

static mrb_value
mrb_hash_has_key(mrb_state *mrb, mrb_value hash)
{
  mrb_value key = mrb_get_arg1(mrb);
  mrb_bool key_p;

  key_p = mrb_hash_key_p(mrb, hash, key);
  return mrb_bool_value(key_p);
}

#keysArray

Returns a new array populated with the keys from this hash. See also Hash#values.

h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
h.keys   #=> ["a", "b", "c", "d"]

Returns:



1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
# File 'mruby/src/hash.c', line 1632

MRB_API mrb_value
mrb_hash_keys(mrb_state *mrb, mrb_value hash)
{
  struct RHash *h = mrb_hash_ptr(hash);
  mrb_value ary = mrb_ary_new_capa(mrb, (mrb_int)h_size(h));
  h_each(h, entry, {
    mrb_ary_push(mrb, ary, entry->key);
  });
  return ary;
}

#lengthInteger #sizeInteger

Returns the number of key-value pairs in the hash.

h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
h.length        #=> 4
h.delete("a")   #=> 200
h.length        #=> 3

Overloads:



1590
1591
1592
1593
1594
1595
# File 'mruby/src/hash.c', line 1590

static mrb_value
mrb_hash_size_m(mrb_state *mrb, mrb_value self)
{
  mrb_int size = mrb_hash_size(mrb, self);
  return mrb_int_value(mrb, size);
}

#member?Boolean

15.2.13.4.21

Returns:

  • (Boolean)


1693
1694
1695
1696
1697
1698
1699
1700
1701
# File 'mruby/src/hash.c', line 1693

static mrb_value
mrb_hash_has_key(mrb_state *mrb, mrb_value hash)
{
  mrb_value key = mrb_get_arg1(mrb);
  mrb_bool key_p;

  key_p = mrb_hash_key_p(mrb, hash, key);
  return mrb_bool_value(key_p);
}

#merge(*others, &block) ⇒ Object

call-seq:

   hsh.merge(other_hash..)                                 -> hsh
   hsh.merge(other_hash..){|key, oldval, newval| block}    -> hsh

Returns the new \Hash formed by merging each of +other_hashes+
into a copy of +self+.

Each argument in +other_hashes+ must be a \Hash.
Adds the contents of _other_hash_ to _hsh_. If no block is specified,
entries with duplicate keys are overwritten with the values from
_other_hash_, otherwise the value of each duplicate key is determined by
calling the block with the key, its value in _hsh_ and its value in
_other_hash_.

Example:
 h = {foo: 0, bar: 1, baz: 2}
 h1 = {bat: 3, bar: 4}
 h2 = {bam: 5, bat:6}
 h3 = h.merge(h1, h2) { |key, old_value, new_value| old_value + new_value }
 h3 # => {:foo=>0, :bar=>5, :baz=>2, :bat=>9, :bam=>5}

ISO 15.2.13.4.22



183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'mruby/mrblib/hash.rb', line 183

def merge(*others, &block)
  i=0; len=others.size
  h = self.dup
  return h.__merge(*others) unless block
  while i<len
    other = others[i]
    i += 1
    raise TypeError, "Hash required (#{other.class} given)" unless Hash === other
    other.each_key{|k|
      h[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
    }
  end
  h
end

#merge!(*others, &block) ⇒ Object Also known as: update

call-seq:

   hsh.merge!(other_hash..)                                 -> hsh
   hsh.merge!(other_hash..){|key, oldval, newval| block}    -> hsh

Adds the contents of _other_hash_ to _hsh_. If no block is specified,
entries with duplicate keys are overwritten with the values from
_other_hash_, otherwise the value of each duplicate key is determined by
calling the block with the key, its value in _hsh_ and its value in
_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}


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 84

def merge!(*others, &block)
  i = 0; len=others.size
  return self.__merge(*others) unless block
  while i<len
    other = others[i]
    i += 1
    raise TypeError, "Hash required (#{other.class} given)" unless Hash === other
    if block
      other.each_key{|k|
        self[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
      }
    else
      other.each_key{|k| self[k] = other[k]}
    end
  end
  self
end

#rehashHash

Rebuilds the hash based on the current hash values for each key. If values of key objects have changed since they were inserted, this method will reindex hsh.

keys = (1..17).map{|n| [n]}
k = keys[0]
h = {}
keys.each{|key| h[key] = key[0]}
h     #=> { [1]=>1, [2]=>2, ... [16]=>16, [17]=>17}
h[k]  #=> 1
k[0] = keys.size + 1
h     #=> {[18]=>1, [2]=>2, ... [16]=>16, [17]=>17}
h[k]  #=> nil
h.rehash
h[k]  #=> 1

Returns:



1783
1784
1785
1786
1787
1788
# File 'mruby/src/hash.c', line 1783

static mrb_value
mrb_hash_rehash(mrb_state *mrb, mrb_value self)
{
  h_rehash(mrb, mrb_hash_ptr(self));
  return self;
}

#reject(&block) ⇒ Object

call-seq:

   hsh.reject {|key, value| block}   -> a_hash
   hsh.reject                        -> an_enumerator

Returns a new hash consisting of entries for which the block returns false.

If no block is given, an enumerator is returned instead.

   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}

1.8/1.9 Hash#reject returns Hash; ISO says nothing.


263
264
265
266
267
268
269
270
271
272
273
# File 'mruby/mrblib/hash.rb', line 263

def reject(&block)
  return to_enum :reject unless block

  h = {}
  self.each{|k,v|
    unless block.call([k, v])
      h[k] = v
    end
  }
  h
end

#reject!(&block) ⇒ Object

call-seq:

   hsh.reject! {| key, value | block }  -> hsh or nil
   hsh.reject!                          -> an_enumerator

Equivalent to <code>Hash#delete_if</code>, but returns
<code>nil</code> if no changes were made.

1.8/1.9 Hash#reject! returns Hash; ISO says nothing.


232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'mruby/mrblib/hash.rb', line 232

def reject!(&block)
  return to_enum :reject! unless block

  keys = []
  self.each{|k,v|
    if block.call([k, v])
      keys.push(k)
    end
  }
  return nil if keys.size == 0
  keys.each{|k|
    self.delete(k)
  }
  self
end

#replaceObject

15.2.13.4.23



1191
1192
1193
1194
1195
1196
1197
1198
1199
# File 'mruby/src/hash.c', line 1191

static mrb_value
mrb_hash_init_copy(mrb_state *mrb, mrb_value self)
{
  mrb_value orig;
  mrb_get_args(mrb, "H", &orig);
  hash_modify(mrb, self);
  if (mrb_hash_ptr(self) != mrb_hash_ptr(orig)) hash_replace(mrb, self, orig);
  return self;
}

#select(&block) ⇒ Object Also known as: filter

call-seq:

   hsh.select {|key, value| block}   -> a_hash
   hsh.select                        -> an_enumerator

Returns a new hash consisting of entries for which the block returns true.

If no block is given, an enumerator is returned instead.

   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}

1.9 Hash#select returns Hash; ISO says nothing


316
317
318
319
320
321
322
323
324
325
326
# File 'mruby/mrblib/hash.rb', line 316

def select(&block)
  return to_enum :select unless block

  h = {}
  self.each{|k,v|
    if block.call([k, v])
      h[k] = v
    end
  }
  h
end

#select!(&block) ⇒ Object Also known as: filter!

call-seq:

   hsh.select! {| key, value | block }  -> hsh or nil
   hsh.select!                          -> an_enumerator

Equivalent to <code>Hash#keep_if</code>, but returns
<code>nil</code> if no changes were made.

1.9 Hash#select! returns Hash; ISO says nothing.


285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'mruby/mrblib/hash.rb', line 285

def select!(&block)
  return to_enum :select! unless block

  keys = []
  self.each{|k,v|
    unless block.call([k, v])
      keys.push(k)
    end
  }
  return nil if keys.size == 0
  keys.each{|k|
    self.delete(k)
  }
  self
end

#shiftArray, Object

Removes a key-value pair from hsh and returns it as the two-item array [ key, value ], or the hash’s default value if the hash is empty.

h = { 1 => "a", 2 => "b", 3 => "c" }
h.shift   #=> [1, "a"]
h         #=> {2=>"b", 3=>"c"}

Returns:



1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
# File 'mruby/src/hash.c', line 1503

static mrb_value
mrb_hash_shift(mrb_state *mrb, mrb_value hash)
{
  struct RHash *h = mrb_hash_ptr(hash);

  hash_modify(mrb, hash);
  if (h_size(h) == 0) {
    return mrb_nil_value();
  }
  else {
    mrb_value del_key, del_val;
    h_shift(mrb, h, &del_key, &del_val);
    mrb_gc_protect(mrb, del_key);
    mrb_gc_protect(mrb, del_val);
    return mrb_assoc_new(mrb, del_key, del_val);
  }
}

#lengthInteger #sizeInteger

Returns the number of key-value pairs in the hash.

h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
h.length        #=> 4
h.delete("a")   #=> 200
h.length        #=> 3

Overloads:



1590
1591
1592
1593
1594
1595
# File 'mruby/src/hash.c', line 1590

static mrb_value
mrb_hash_size_m(mrb_state *mrb, mrb_value self)
{
  mrb_int size = mrb_hash_size(mrb, self);
  return mrb_int_value(mrb, size);
}

#slice(*keys) ⇒ Hash

Returns a hash containing only the given keys and their values.

h = { a: 100, b: 200, c: 300 }
h.slice(:a)           #=> {:a=>100}
h.slice(:b, :c, :d)   #=> {:b=>200, :c=>300}

Returns:



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'mruby/mrbgems/mruby-hash-ext/src/hash-ext.c', line 51

static mrb_value
hash_slice(mrb_state *mrb, mrb_value hash)
{
  const mrb_value *argv;
  mrb_value result;
  mrb_int argc, i;

  mrb_get_args(mrb, "*", &argv, &argc);
  result = mrb_hash_new_capa(mrb, argc);
  if (argc == 0) return result; /* empty hash */
  for (i = 0; i < argc; i++) {
    mrb_value key = argv[i];
    mrb_value val;

    val = mrb_hash_fetch(mrb, hash, key, mrb_undef_value());
    if (!mrb_undef_p(val)) {
      mrb_hash_set(mrb, result, key, val);
    }
  }
  return result;
}

#[]=(key) ⇒ Object #store(key, value) ⇒ Object

Element Assignment—Associates the value given by value with the key given by key. key should not have its value changed while it is in use as a key (a String passed as a key will be duplicated and frozen).

h = { "a" => 100, "b" => 200 }
h["a"] = 9
h["c"] = 4
h   #=> {"a"=>9, "b"=>200, "c"=>4}


1560
1561
1562
1563
1564
1565
1566
1567
1568
# File 'mruby/src/hash.c', line 1560

static mrb_value
mrb_hash_aset(mrb_state *mrb, mrb_value self)
{
  mrb_value key, val;

  mrb_get_args(mrb, "oo", &key, &val);
  mrb_hash_set(mrb, self, key, val);
  return val;
}

#to_hObject

call-seq:

   hsh.to_h     -> hsh or new_hash

Returns +self+. If called on a subclass of Hash, converts
the receiver to a Hash object.


299
300
301
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 299

def to_h
  self
end

#to_procObject



473
474
475
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 473

def to_proc
  ->x{self[x]}
end

#transform_keys(&block) ⇒ Object

call-seq:

hsh.transform_keys {|key| block } -> new_hash
hsh.transform_keys                -> an_enumerator

Returns a new hash, with the keys computed from running the block once for each key in the hash, and the values unchanged.

If no block is given, an enumerator is returned instead.



410
411
412
413
414
415
416
417
418
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 410

def transform_keys(&block)
  return to_enum :transform_keys unless block
  hash = {}
  self.keys.each do |k|
    new_key = block.call(k)
    hash[new_key] = self[k]
  end
  hash
end

#transform_keys!(&block) ⇒ Object

call-seq:

hsh.transform_keys! {|key| block } -> hsh
hsh.transform_keys!                -> an_enumerator

Invokes the given block once for each key in hsh, replacing it with the new key returned by the block, and then returns hsh.

If no block is given, an enumerator is returned instead.



429
430
431
432
433
434
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 429

def transform_keys!(&block)
  return to_enum :transform_keys! unless block
  hash = self.transform_keys(&block)
  self.replace(hash)
  self
end

#transform_values(&b) ⇒ Object

call-seq:

hsh.transform_values {|value| block } -> new_hash
hsh.transform_values                  -> an_enumerator

Returns a new hash with the results of running the block once for every value. This method does not change the keys.

If no block is given, an enumerator is returned instead.



446
447
448
449
450
451
452
453
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 446

def transform_values(&b)
  return to_enum :transform_values unless block_given?
  hash = {}
  self.keys.each do |k|
    hash[k] = yield(self[k])
  end
  hash
end

#transform_values!(&b) ⇒ Object

call-seq:

hsh.transform_values! {|key| block } -> hsh
hsh.transform_values!                -> an_enumerator

Invokes the given block once for each value in the hash, replacing with the new value returned by the block, and then returns hsh.

If no block is given, an enumerator is returned instead.



465
466
467
468
469
470
471
# File 'mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb', line 465

def transform_values!(&b)
  return to_enum :transform_values! unless block_given?
  self.keys.each do |k|
    self[k] = yield(self[k])
  end
  self
end

#has_value?(value) ⇒ Boolean #value?(value) ⇒ Boolean

Returns true if the given value is present for some key in hsh.

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

Overloads:

  • #has_value?(value) ⇒ Boolean

    Returns:

    • (Boolean)
  • #value?(value) ⇒ Boolean

    Returns:

    • (Boolean)


1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
# File 'mruby/src/hash.c', line 1718

static mrb_value
mrb_hash_has_value(mrb_state *mrb, mrb_value hash)
{
  mrb_value val = mrb_get_arg1(mrb);
  struct RHash *h = mrb_hash_ptr(hash);
  h_each(h, entry, {
    h_check_modified(mrb, h, {
      if (mrb_equal(mrb, val, entry->val)) return mrb_true_value();
    });
  });
  return mrb_false_value();
}

#valuesArray

Returns a new array populated with the values from hsh. See also Hash#keys.

h = { "a" => 100, "b" => 200, "c" => 300 }
h.values   #=> [100, 200, 300]

Returns:



1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
# File 'mruby/src/hash.c', line 1656

MRB_API mrb_value
mrb_hash_values(mrb_state *mrb, mrb_value hash)
{
  struct RHash *h = mrb_hash_ptr(hash);
  mrb_value ary = mrb_ary_new_capa(mrb, (mrb_int)h_size(h));
  h_each(h, entry, {
    mrb_ary_push(mrb, ary, entry->val);
  });
  return ary;
}

#values_at(key, ...) ⇒ Array

Return an array containing the values associated with the given keys. Also see Hash.select.

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

Returns:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'mruby/mrbgems/mruby-hash-ext/src/hash-ext.c', line 22

static mrb_value
hash_values_at(mrb_state *mrb, mrb_value hash)
{
  const mrb_value *argv;
  mrb_value result;
  mrb_int argc, i;
  int ai;

  mrb_get_args(mrb, "*", &argv, &argc);
  result = mrb_ary_new_capa(mrb, argc);
  if (argc == 0) return result;
  ai = mrb_gc_arena_save(mrb);
  for (i = 0; i < argc; i++) {
    mrb_ary_push(mrb, result, mrb_hash_get(mrb, hash, argv[i]));
    mrb_gc_arena_restore(mrb, ai);
  }
  return result;
}