class Hash

Public Class Methods

zip(keys, values) click to toggle source
# File lib/lite/ruby/hash.rb, line 7
def zip(keys, values)
  keys.size.times.with_object({}) { |i, hash| hash[keys[i]] = values[i] }
end

Public Instance Methods

aka(new_key, old_key) click to toggle source
# File lib/lite/ruby/hash.rb, line 13
def aka(new_key, old_key)
  self[new_key] = self[old_key] if key?(old_key)
  self
end
assert_all_min_keys!(*valid_keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 32
def assert_all_min_keys!(*valid_keys)
  return assert_min_keys!(*valid_keys) unless empty?

  raise ArgumentError, 'An empty hash is not allowed'
end
assert_all_pair_presence!(*valid_keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 50
def assert_all_pair_presence!(*valid_keys)
  return assert_pair_presence!(*valid_keys) unless empty?

  raise ArgumentError, 'An empty hash is not allowed'
end
assert_all_valid_keys!(*valid_keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 66
def assert_all_valid_keys!(*valid_keys)
  return assert_valid_keys!(*valid_keys) unless empty?

  raise ArgumentError, 'An empty hash is not allowed'
end
assert_all_valid_values!(*valid_values) click to toggle source
# File lib/lite/ruby/hash.rb, line 82
def assert_all_valid_values!(*valid_values)
  return assert_valid_values!(*valid_values) unless empty?

  raise ArgumentError, 'An empty hash is not allowed'
end
assert_min_keys!(*valid_keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 18
def assert_min_keys!(*valid_keys)
  return self if empty?

  valid_keys.each do |key|
    next if key?(key)

    raise ArgumentError,
          "Missing key: #{key.inspect}. " \
          "Minimum keys are: #{valid_keys.map(&:inspect).join(', ')}"
  end

  self
end
assert_pair_presence!(*valid_keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 38
def assert_pair_presence!(*valid_keys)
  each do |key, value|
    if !valid_keys.include?(key)
      raise ArgumentError,
            "Invalid key: #{key.inspect}. " \
            "Allowed keys are: #{valid_keys.map(&:inspect).join(', ')}"
    elsif value.respond_to?(:blank?) ? value.blank? : !value
      raise ArgumentError, "A #{value.inspect} value for #{key.inspect} is not allowed"
    end
  end
end
assert_valid_keys!(*valid_keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 56
def assert_valid_keys!(*valid_keys)
  each_key do |key|
    next if valid_keys.include?(key)

    raise ArgumentError,
          "Invalid key: #{key.inspect}. " \
          "Allowed keys are: #{valid_keys.map(&:inspect).join(', ')}"
  end
end
assert_valid_values!(*valid_values) click to toggle source
# File lib/lite/ruby/hash.rb, line 72
def assert_valid_values!(*valid_values)
  each_value do |value|
    next if valid_values.include?(value)

    raise ArgumentError,
          "Invalid value: #{value.inspect}. " \
          "Allowed values are: #{valid_values.map(&:inspect).join(', ')}"
  end
end
bury(*args) click to toggle source

rubocop:disable Style/GuardClause

# File lib/lite/ruby/hash.rb, line 89
def bury(*args)
  if args.count < 2
    raise ArgumentError, '2 or more arguments required'
  elsif args.count == 2
    self[args[0]] = args[1]
  else
    arg = args.shift
    self[arg] = {} unless self[arg]
    self[arg].bury(*args) unless args.empty?
  end

  self
end
collate(*others) click to toggle source

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength

# File lib/lite/ruby/hash.rb, line 105
def collate(*others)
  hash = {}

  each_key { |key| hash[key] = [] }

  others.each do |other|
    other.each_key { |key| hash[key] = [] }
  end

  each { |key, val| hash[key] << val }

  others.each do |other|
    other.each { |key, val| hash[key] << val }
  end

  hash.each_value(&:flatten!)
  hash
end
collate!(other_hash) click to toggle source

rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength

# File lib/lite/ruby/hash.rb, line 125
def collate!(other_hash)
  replace(collate(other_hash))
end
collect_keys(&block) click to toggle source
# File lib/lite/ruby/hash.rb, line 129
def collect_keys(&block)
  keys.map(&block)
end
Also aliased as: map_keys
collect_values(&block) click to toggle source
# File lib/lite/ruby/hash.rb, line 133
def collect_values(&block)
  values.map(&block)
end
Also aliased as: map_values
dearray_singular_values() click to toggle source
# File lib/lite/ruby/hash.rb, line 150
def dearray_singular_values
  each_with_object({}) do |(key, val), hash|
    hash[key] = case val
                when Array then val.size < 2 ? val[0] : val
                else val
                end
  end
end
dearray_singular_values!() click to toggle source
# File lib/lite/ruby/hash.rb, line 159
def dearray_singular_values!
  replace(dearray_singular_values)
end
dearray_values(idx = 0) click to toggle source
# File lib/lite/ruby/hash.rb, line 137
def dearray_values(idx = 0)
  each_with_object({}) do |(key, val), hash|
    hash[key] = case val
                when Array then val[idx] || val[-1]
                else val
                end
  end
end
dearray_values!(idx = 0) click to toggle source
# File lib/lite/ruby/hash.rb, line 146
def dearray_values!(idx = 0)
  replace(dearray_values(idx))
end
deep_dup() click to toggle source

rubocop:disable Style/CaseEquality

# File lib/lite/ruby/safe/hash.rb, line 6
def deep_dup
  hash = dup

  each_pair do |key, value|
    if key.frozen? && ::String === key
      hash[key] = value.deep_dup
    else
      hash.delete(key)
      hash[key.deep_dup] = value.deep_dup
    end
  end

  hash
end
deep_key?(*keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 163
def deep_key?(*keys)
  last_hash = self
  found_key = false

  keys.each do |key|
    break found_key = false unless last_hash.key?(key)

    last_hash = last_hash[key]
    found_key = true
  end

  found_key
end
deep_merge(other_hash, &block) click to toggle source

rubocop:enable Style/CaseEquality

# File lib/lite/ruby/safe/hash.rb, line 22
def deep_merge(other_hash, &block)
  dup.deep_merge!(other_hash, &block)
end
deep_merge!(other_hash) { || ... } click to toggle source
# File lib/lite/ruby/safe/hash.rb, line 26
def deep_merge!(other_hash, &block)
  merge!(other_hash) do |key, this_val, other_val|
    if this_val.is_a?(Hash) && other_val.is_a?(Hash)
      this_val.deep_merge(other_val, &block)
    elsif defined?(yield)
      yield(key, this_val, other_val)
    else
      other_val
    end
  end
end
delete_unless() { |key, val| ... } click to toggle source
# File lib/lite/ruby/hash.rb, line 177
def delete_unless
  delete_if { |key, val| !yield(key, val) }
end
delete_values(*values) click to toggle source
# File lib/lite/ruby/hash.rb, line 181
def delete_values(*values)
  each_key.with_object([]) do |key, array|
    next unless values.include?(self[key])

    array << key
    delete(key)
  end
end
demote(key) click to toggle source
# File lib/lite/ruby/hash.rb, line 190
def demote(key)
  dup.demote!(key)
end
demote!(key) click to toggle source
# File lib/lite/ruby/hash.rb, line 194
def demote!(key)
  return self unless key?(key)

  self[key] = delete(key)
  self
end
denillify(identity = 0) click to toggle source
# File lib/lite/ruby/hash.rb, line 201
def denillify(identity = 0)
  dup.denillify!(identity)
end
denillify!(identity = 0) click to toggle source
# File lib/lite/ruby/hash.rb, line 205
def denillify!(identity = 0)
  each { |key, val| self[key] = val || identity }
end
diff(hash) click to toggle source
# File lib/lite/ruby/hash.rb, line 209
def diff(hash)
  h1 = dup.delete_if { |k, v| hash[k] == v }
  h2 = hash.dup.delete_if { |k, _| key?(k) }
  h1.merge(h2)
end
except(*keys) click to toggle source
# File lib/lite/ruby/safe/hash.rb, line 38
def except(*keys)
  slice(*self.keys - keys)
end
except!(*keys) click to toggle source
# File lib/lite/ruby/safe/hash.rb, line 42
def except!(*keys)
  keys.each { |key| delete(key) }
  self
end
extract!(*keys) click to toggle source
# File lib/lite/ruby/safe/hash.rb, line 47
def extract!(*keys)
  keys.each_with_object({}) { |key, hash| hash[key] = delete(key) if key?(key) }
end
has_keys?(*check_keys)
Alias for: keys?
has_only_keys?(*check_keys)
Alias for: only_keys?
hmap(&block) click to toggle source
# File lib/lite/ruby/hash.rb, line 215
def hmap(&block)
  dup.hmap!(&block)
end
hmap!() { |key, val| ... } click to toggle source
# File lib/lite/ruby/hash.rb, line 219
def hmap!
  inject(self) { |hash, (key, val)| hash.merge(yield(key, val)) }
end
insert(name, value) click to toggle source
# File lib/lite/ruby/hash.rb, line 223
def insert(name, value)
  return false if key?(name)

  store(name, value)
  true
end
invert() click to toggle source
# File lib/lite/ruby/hash.rb, line 230
def invert
  each_pair.with_object({}) do |(key, val), hash|
    if val.is_a?(Array)
      val.each { |x| hash[x] = (hash.key?(x) ? [key, hash[x]].flatten : key) }
    else
      hash[val] = (hash.key?(val) ? [key, hash[val]].flatten : key)
    end
  end
end
keys?(*check_keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 240
def keys?(*check_keys)
  unknown_keys = check_keys - keys
  unknown_keys.empty?
end
Also aliased as: has_keys?
map_keys(&block)
Alias for: collect_keys
map_values(&block)
Alias for: collect_values
nillify() click to toggle source
# File lib/lite/ruby/hash.rb, line 245
def nillify
  dup.nillify!
end
nillify!() click to toggle source
# File lib/lite/ruby/hash.rb, line 249
def nillify!
  each do |key, val|
    next if val.nil?

    self[key] = nil if respond_to?(:blank?) ? val.blank? : !val
  end
end
only!(*keys)
Alias for: slice!
only_fill(*keys, placeholder: nil) click to toggle source
# File lib/lite/ruby/hash.rb, line 257
def only_fill(*keys, placeholder: nil)
  keys.each_with_object({}) { |key, hash| hash[key] = key?(key) ? self[key] : placeholder }
end
only_fill!(*keys, placeholder: nil) click to toggle source
# File lib/lite/ruby/hash.rb, line 261
def only_fill!(*keys, placeholder: nil)
  replace(only_fill(*keys, placeholder: placeholder))
end
only_keys?(*check_keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 265
def only_keys?(*check_keys)
  unknown_keys = keys - check_keys
  unknown_keys.empty?
end
Also aliased as: has_only_keys?
pair?(key, value) click to toggle source
# File lib/lite/ruby/hash.rb, line 270
def pair?(key, value)
  self[key] == value
end
promote(key) click to toggle source
# File lib/lite/ruby/hash.rb, line 274
def promote(key)
  dup.promote!(key)
end
promote!(key) click to toggle source
# File lib/lite/ruby/hash.rb, line 278
def promote!(key)
  return self unless key?(key)

  { key => delete(key) }.merge(self)
end
rename_keys(*keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 284
def rename_keys(*keys)
  dup.rename_keys!(*keys)
end
rename_keys!(*keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 288
def rename_keys!(*keys)
  keys = Hash[*keys]
  keys.each_with_object(self) { |(key, val), hash| hash[val] = delete(key) if hash[key] }
end
reverse_merge(other_hash) click to toggle source
# File lib/lite/ruby/safe/hash.rb, line 51
def reverse_merge(other_hash)
  other_hash.merge(self)
end
reverse_merge!(other_hash) click to toggle source
# File lib/lite/ruby/safe/hash.rb, line 55
def reverse_merge!(other_hash)
  other_hash.merge!(self)
end
sample() click to toggle source
# File lib/lite/ruby/hash.rb, line 293
def sample
  key = sample_key
  [key, fetch(key)]
end
sample!() click to toggle source
# File lib/lite/ruby/hash.rb, line 298
def sample!
  key, value = sample
  delete(key)
  [key, value]
end
sample_key() click to toggle source
# File lib/lite/ruby/hash.rb, line 304
def sample_key
  hash_keys = keys
  hash_keys.at(Random.rand(hash_keys.size - 1))
end
sample_key!() click to toggle source
# File lib/lite/ruby/hash.rb, line 309
def sample_key!
  key, _val = sample
  delete(key)
  key
end
sample_value() click to toggle source
# File lib/lite/ruby/hash.rb, line 315
def sample_value
  fetch(sample_key)
end
sample_value!() click to toggle source
# File lib/lite/ruby/hash.rb, line 319
def sample_value!
  key, value = sample
  delete(key)
  value
end
shuffle() click to toggle source
# File lib/lite/ruby/hash.rb, line 325
def shuffle
  to_a.sample(size).to_h
end
shuffle!() click to toggle source
# File lib/lite/ruby/hash.rb, line 329
def shuffle!
  replace(shuffle)
end
slice!(*keys) click to toggle source
# File lib/lite/ruby/hash.rb, line 333
def slice!(*keys)
  omit = slice(*self.keys - keys)
  hash = slice(*keys)
  hash.default = default
  hash.default_proc = default_proc if default_proc
  replace(hash)
  omit
end
Also aliased as: only!
stringify_keys() click to toggle source
# File lib/lite/ruby/safe/hash.rb, line 59
def stringify_keys
  transform_keys(&:to_s)
end
stringify_keys!() click to toggle source
# File lib/lite/ruby/safe/hash.rb, line 63
def stringify_keys!
  transform_keys!(&:to_s)
end
strip() click to toggle source
# File lib/lite/ruby/hash.rb, line 342
def strip
  reject { |_, val| respond_to?(:blank?) ? val.blank? : !val }
end
strip!() click to toggle source
# File lib/lite/ruby/hash.rb, line 346
def strip!
  reject! { |_, val| respond_to?(:blank?) ? val.blank? : !val }
end
symbolize_and_underscore_keys() click to toggle source

rubocop:disable Metrics/MethodLength

# File lib/lite/ruby/hash.rb, line 351
def symbolize_and_underscore_keys
  each_with_object({}) do |(key, val), hash|
    new_key = begin
      str = key.dup.to_s
      str.gsub!(/::/, '/') || str
      str.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2') || str
      str.gsub!(/([a-z\d])([A-Z])/, '\1_\2') || str
      str.tr!(' -', '_') || str
      str.downcase!
      str.to_sym
    rescue StandardError
      key
    end

    hash[new_key] = val
  end
end
symbolize_and_underscore_keys!() click to toggle source

rubocop:enable Metrics/MethodLength

# File lib/lite/ruby/hash.rb, line 370
def symbolize_and_underscore_keys!
  replace(symbolize_and_underscore_keys)
end
symbolize_keys() click to toggle source
# File lib/lite/ruby/safe/hash.rb, line 67
def symbolize_keys
  transform_keys do |key|
    key.to_sym
  rescue StandardError
    key
  end
end
symbolize_keys!() click to toggle source
# File lib/lite/ruby/safe/hash.rb, line 75
def symbolize_keys!
  transform_keys! do |key|
    key.to_sym
  rescue StandardError
    key
  end
end
to_o()
Alias for: to_object
to_object() click to toggle source
# File lib/lite/ruby/hash.rb, line 374
def to_object
  JSON.parse(to_json, object_class: OpenStruct)
end
Also aliased as: to_o
to_open_struct(lazy: true) click to toggle source
# File lib/lite/ruby/hash.rb, line 378
def to_open_struct(lazy: true)
  struct = OpenStruct.new(self)
  struct.methods(lazy)
  struct
end
to_struct() click to toggle source
# File lib/lite/ruby/hash.rb, line 384
def to_struct
  struct = Struct.new(*keys)
  struct.new(*values)
end
update_each() { |key, val| ... } click to toggle source
# File lib/lite/ruby/hash.rb, line 389
def update_each
  replace(each_with_object({}) { |(key, val), hash| hash.update(yield(key, val)) })
end
update_keys() { || ... } click to toggle source
# File lib/lite/ruby/hash.rb, line 393
def update_keys
  return to_enum(:update_keys) unless defined?(yield)

  replace(each_with_object({}) { |(key, val), hash| hash[yield(key)] = val })
end
update_values() { || ... } click to toggle source
# File lib/lite/ruby/hash.rb, line 399
def update_values
  return to_enum(:update_values) unless defined?(yield)

  replace(each_with_object({}) { |(key, val), hash| hash[key] = yield(val) })
end
vacant?(key) click to toggle source
# File lib/lite/ruby/hash.rb, line 405
def vacant?(key)
  value = self[key]
  respond_to?(:blank?) ? value.blank? : !value
end