Last active
March 9, 2024 17:57
-
-
Save watzon/acd7ac39be86a86ed5ea1c3340432c8d to your computer and use it in GitHub Desktop.
Crystal language snippets
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
# Creates a `#==` method for a class or module. | |
# Parameters: | |
# args [Array(Tuple(Symbol, Symbol))] A list of properties to | |
# use for comparison. The first will be for a method/variable | |
# in the current class or module, the second will apply to the | |
# other. | |
# other_class [Class] The class to compare this one with | |
# strict [Bool] Set to false to compare with parent classes too | |
macro equalize(*args, other_class = nil, strict = true) | |
{{ other_class = other_class ? other_class.id : @type.id }} | |
def ==(other : {{ other_class }}) | |
{% if strict %} | |
return false unless other.class == {{ other_class }} | |
{% end %} | |
{% for arg in args %} | |
return false unless {{ arg.first.id }} == other.{{ arg.last.id }} | |
{% end %} | |
true | |
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
class Hash(K, V) | |
# 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. | |
# | |
# ``` | |
# hash = {"a" => {"b" => {"c" => "c"}}} | |
# hash.dig("a", "b", "c") # => "c" | |
# hash.dig("a", "b", "c", "d") # => nil | |
# ``` | |
def dig(*args : K) | |
args.reduce(self) do |acc, i| | |
if acc.responds_to?(:fetch) | |
acc.fetch(i, nil) | |
else | |
nil | |
end | |
end | |
end | |
# Returns a new hash with all keys converted using the block operation. | |
# The block can change a type of keys. | |
# | |
# ``` | |
# hash = {:a => 1, :b => 2, :c => 3} | |
# hash.map_keys { |key| key.to_s } # => {"A" => 1, "B" => 2, "C" => 3} | |
# ``` | |
def map_keys(&block : K -> K2) forall K2 | |
each_with_object({} of K2 => V) do |(key, value), memo| | |
memo[yield(key)] = value | |
end | |
end | |
# Returns a new hash with the results of running block once for every value. | |
# The block can change a type of values. | |
# | |
# ``` | |
# hash = {:a => 1, :b => 2, :c => 3} | |
# hash.map_values { |value| value + 1 } # => {:a => 2, :b => 3, :c => 4} | |
def map_values(&block : V -> V2) forall V2 | |
each_with_object({} of K => V2) do |(key, value), memo| | |
memo[key] = yield(value) | |
end | |
end | |
# Destructively transforms all keys using a block. Same as map_keys but modifies in place. | |
# The block cannot change a type of keys. | |
# | |
# ``` | |
# hash = {"a" => 1, "b" => 2, "c" => 3} | |
# hash.map_keys! { |key| key.succ } | |
# hash # => {"b" => 1, "c" => 2, "d" => 3} | |
def map_keys!(&block : K -> K) | |
current = @first | |
while current | |
current.key = yield(current.key) | |
current = current.fore | |
end | |
end | |
# Destructively transforms all values using a block. Same as map_values but modifies in place. | |
# The block cannot change a type of values. | |
# | |
# ``` | |
# hash = {:a => 1, :b => 2, :c => 3} | |
# hash.map_values! { |value| value + 1 } | |
# hash # => {:a => 2, :b => 3, :c => 4} | |
def map_values!(&block : V -> V) | |
current = @first | |
while current | |
current.value = yield(current.value) | |
current = current.fore | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment