Хешът е структура от данни, която записва данни под формата на двойки ключ-стойност. Стойностите в хеша са подредени в реда, в който са били вмъкнати в хеша.

Хеш ключът може да бъде всеки тип обект, низ, цяло число, символи и т.н.

new_hash = {a: 1, b: 5, c: 6} # symbols as hash keys
new_hash_2 = {“a” => 2, “b” => 4} # string as hash keys
print new_hash[:a], new_hash_2[“a”], new_hash[:p], new_hash_2[“p”]
1, 2, nil, nil
# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — # can not have duplicate key in the hash
# first value will be ignored with a warning
new_hash_2 = {“a” => 4, “a” => 55}
print new_hash_2
{“a” => 55}
# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — # other ways to create hashes
other_hash = Hash.new
print other_hash
{}
other_hash[:a] = 1
other_hash[:b] = 5
print other_hash
{a: 1, b: 5}
other_hash[:a] = 15 # duplicate key, previous key value will be updated
print other_hash
{a: 15, b: 5}
other_hash.default = 88 #default value for keys
print other_hash[“pass”]
88 # prints 88 instead of nil

Методи за хеширане

  • празен хеш, чрез нулиране на всички двойки ключ стойност
# clear
a = {a: 5, b: 3, c: 2}
print a
{:a=>5, :b=>3, :c=>2}
a.clear
print a
{}
  • изтрийте предоставен ключ от хеша
# delete
a = {a: 5, b: 3, c: 2}
a.delete(:a) #returns the value of given key, if exists
5
print a
{:b => 3, :c => 2}
a.delete(:h) #returns nil if key does not exists
nil
print a
{:a => 5, :b => 3, :c => 2}
  • проверете дали предоставеният ключ съществува в масива или не
# has_key?/include?/key?/member?
a = {a: 5, b: 3, c: 2}
a.has_key?(:a), a.include?(:a), a.key?(:a), a.member?(:a)
true, true, true, true
a.has_key?(:g), a.include?(:g), a.key?(:g), a.member?(:g)
false,false, false, false
  • вземете стойността на предоставения ключ
# fetch/dig
a = {a: 5, b: 3, c: 2}
a.fetch(:a), a.dig(:a)
5, 5

Разлика между копаене и извличане

# fetch throws an error if the given key does not exists in the hash
a.fetch(:g)
>> KeyError (key not found: :f)
# dig returns nil
a.dig(:g)
nil
#-------------------------------------------------------------------
# can also return a default value if key not found
a.fetch(:g, 6), a.dig(:g, 6)
6, nil
#-------------------------------------------------------------------
# access nested key
user = {
   name: {
     first: "sanju",
     last: "yadav"
   }
}
user.fetch(:name).fetch(:first), user.dig(:name, :first)
"sanju", "sanju"
# dig returns nil if key is not present, but fetch raises the error
user.fetch(:name1).fetch(:first)
>> KeyError (key not found: :name1)
Did you mean?  :name
user.dig(:name1, :first)
nil
  • проверете дали хешът е празен или не
# empty?
a = {a: 5, b: 3, c: 2}
b = {}
print a.empty?, b.empty?
false, true
  • вземете всички ключове на хеша
# keys
a = {a: 5, b: 3, c: 2}
print a.keys()
[:a, :b, :c]
# only returns the first level of keys
user = {
   name: {
     first: "sanju",
     last: "yadav"
   }
}
print user.keys()
[:name]
  • вземете всички стойности на хеша
# values
a = {a: 5, b: 3, c: 2}
print a.values()
[5, 3, 2]
# only returns the first level of values
user = {
   name: {
     first: "sanju",
     last: "yadav"
   }
}
print user.keys()
[{:first_name=>"sanju", :last_name=>"yadav"}]
  • преобразувайте ключове в стойности и стойности в ключове
# invert
a = {a: 5, b: 3, c: 2}
print a.invert
{5 => :a, 3 => :b, 2 => :c}

Промяна на хеша

  • изтриване на двойка ключ-стойност от хеш въз основа на условие
# delete_if, reject
a = {a: 5, b: 3, c: 2}
a.delete_if{|key, value| value % 2 == 0}
{:a => 5, :b => 3}
print a
{:a => 5, :b => 3} # original hash is modified
#--------------------------------------------------------------
a.reject{|key, value| value % 2 == 0}
{:a => 5, :b => 3}
print a
{:a => 5, :b => 3, :c => 2} # original hash is not modified by reject, new hash is returned, use reject! to modify hash inplace
  • изберете двойка ключ-стойност от хеш въз основа на условие
# keep_if, select
a = {a: 5, b: 3, c: 2}
a.keep_if{|key, value| value % 2 == 0}
{:c => 2}
print a
{:c => 2} # original hash is modified
#--------------------------------------------------------------
a.select{|key, value| value % 2 == 0}
{:c => 2}
print a
{:a => 5, :b => 3, :c => 2} # original hash is not modified by select, new hash is returned, use select! to modify hash inplace
  • добавете елементи от един хеш в друг хеш
# merge
a = {a: 5, b: 3, c: 2}
b = {a: 14, f: 45, g: 56}
# a new hash is returned where in case of duplicate keys, key from the second hash is used for the value
a.merge(b)
{:a => 14, :b => 3, :c => 2, :f => 45, :g => 56}
print a, b
{:a => 5, :b => 3, :c => 2}, {:a => 14, :f => 45, :g => 56}
# inplace merge
a.merge!(b)
{:a => 14, :b => 3, :c => 2, :f => 45, :g => 56}
print a, b
{:a => 14, :b => 3, :c => 2, :f => 45, :g => 56}, {:a => 14, :f => 45, :g => 56}
# use a block to determine the which value is used in case of duplicate keys
a.merge!(b){|key, v1, v2| v1}
{:a => 5, :b => 3, :c => 2, :f => 45, :g => 56}
  • конвертиране на елементи в масив
# to_a
a = {a: 5, b: 3, c: 2}
a.to_a
[[:a, 5], [:b, 3], [:c, 2], [:f, 45], [:g, 56]]

Итериране на хеш

  • повторете всеки елемент
# each
a = {a: 5, b: 3, c: 2}
a.each{ |key, value| puts "#{key} - #{value}" }
a - 5
b - 3 
c - 2
  • итерация върху хеш ключове
# each_key
a = {a: 5, b: 3, c: 2}
a.each_key{ |key| puts "#{key}" }
a
b
c
  • итерация върху хеш стойности
# each_value
a = {a: 5, b: 3, c: 2}
a.each_value{ |value| puts "#{value}" }
5
3
2