Skip to content

Commit

Permalink
Add NamedTuple#merge(other : NamedTuple)
Browse files Browse the repository at this point in the history
Merges two named tuples into a new one.  If both tuples define a value
for the same key, the value of the *other* tuple is used.
  • Loading branch information
Papierkorb committed Jul 7, 2017
1 parent 158a818 commit 7f4d366
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
6 changes: 6 additions & 0 deletions spec/std/named_tuple_spec.cr
Expand Up @@ -296,4 +296,10 @@ describe "NamedTuple" do
tup = {a: 1, b: 'a'}
tup.values.should eq({1, 'a'})
end

it "merges with other named tuple" do
a = {one: 1, two: 2, three: 3, four: 4, five: 5}
b = {two: "Two", three: true}
c = a.merge(b).merge(four: "Four").should eq({one: 1, two: "Two", three: true, four: "Four", five: 5})
end
end
22 changes: 22 additions & 0 deletions src/named_tuple.cr
Expand Up @@ -159,6 +159,28 @@ struct NamedTuple
yield
end

# Merges two named tuples into one, returning a new named tuple.
# If a key is defined in both tuples, the value and its type is used from *other*.
#
# ```
# a = {foo: "Hello", bar: "Old"}
# b = {bar: "New", baz: "Bye"}
# a.merge(b) # => {foo: "Hello", bar: "New", baz: "Bye"}
# ```
def merge(other : NamedTuple)
merge(**other)
end

# ditto
def merge(**other : **U) forall U
{% begin %}
{
{% for k in T %} {% unless U.keys.includes?(k) %} {{k}}: self[:{{k}}],{% end %} {% end %}
{% for k in U %} {{k}}: other[:{{k}}], {% end %}
}
{% end %}
end

# Returns a hash value based on this name tuple's size, keys and values.
#
# See also: `Object#hash`.
Expand Down

0 comments on commit 7f4d366

Please sign in to comment.