Created
April 1, 2021 19:31
-
-
Save jvmvik/a450024c5981bd994547cc84a27a01c9 to your computer and use it in GitHub Desktop.
Ruby - Monkey patch the basic hash and array for more productivity
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Monkey patch Ruby Array class | |
# | |
class Array | |
def each_with_last | |
size = self.size | |
each_with_index do |e, index| | |
yield(e, (index == size-1)) | |
end | |
end | |
def deep_copy() | |
new_array = [] | |
self.each do |item| | |
new_array << item.dup | |
end | |
return new_array | |
end | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Monkey patch for Hash | |
# | |
# - Merge recursively | |
# - Sorting | |
# - Deep freeze | |
# | |
class Hash | |
# Sort hash | |
# | |
def sort(hash = self) | |
if hash.class == Hash | |
h = Hash.new | |
hash.keys.map(&:to_s).sort.each do |k| | |
h[k] = hash[k] | |
if h[k].class == Hash | |
h[k] = h[k].sort | |
elsif h[k].class == Array | |
h[k].each_with_index do |e, i| | |
next if e.class != Hash | |
h[k][i] = e.sort | |
end | |
end | |
end | |
return h | |
end | |
return hash | |
end | |
# copy nested hash into another hash | |
# reason: clone operation do not consider nested object | |
# | |
def copy(hash, base = self) | |
base.each do |key, v| | |
if v.is_a?(Hash) | |
hash[key] = Hash.new unless hash[key] | |
copy(hash[key], v) | |
else | |
hash[key] = v | |
end | |
end | |
return hash | |
end | |
# deep clone | |
# @return [Hash] hash which true clone | |
def deep_clone | |
h = {} | |
copy(h) | |
return h | |
end | |
# freeze recursively | |
# | |
def recursive_freeze | |
base = self | |
base.keys.each do |key| | |
if base[key].is_a?(Hash) | |
base[key].recursive_freeze | |
else | |
base[key].freeze | |
end | |
end | |
base.freeze | |
end | |
# usage: | |
# mxp['port']['device'].each_port do |port_number, port_string, dev_list| | |
def each_port | |
self.each do |key, value| | |
next unless key =~ /^p(\d)$/ | |
yield($1.to_i, key, value) | |
end | |
end | |
# Recursive merge of two hash | |
# The primary hash is modified by this merge | |
# | |
def recursive_merge(hash = nil) | |
return self unless hash.is_a?(Hash) | |
base = self | |
hash.each do |key, v| | |
if base[key].is_a?(Hash) && hash[key].is_a?(Hash) | |
base[key].recursive_merge(hash[key].dup) | |
elsif hash[key].is_a?(Hash) | |
base[key]= hash[key].dup | |
else | |
base[key]= hash[key] | |
end | |
end | |
base | |
end | |
# Recursive update all keys with new value | |
# The hash can be composed of hashs and arrays | |
def recursive_update(key, new_value, hash=self) | |
# replace value | |
if hash.respond_to?(:key?) && hash.key?(key) | |
hash[key] = new_value | |
end | |
# recurse through hash structure | |
hash.values.each do |v| | |
if v.class == Hash | |
v.recursive_update(key, new_value) | |
elsif v.class == Array | |
v.each do |e| | |
if e.class == Hash | |
e.recursive_update(key, new_value) | |
end | |
end | |
end | |
end | |
end | |
# Freeze recursively | |
# | |
def deep_freeze | |
base = self | |
base.keys.each do |key| | |
if base[key].is_a?(Hash) | |
base[key].deep_freeze | |
else | |
base[key].freeze | |
end | |
end | |
base.freeze | |
end | |
def deep_freeze! | |
deep_freeze | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment