Skip to content

Commit

Permalink
Add NamedTuple#merge(other : NamedTuple) (#4688)
Browse files Browse the repository at this point in the history
* Add NamedTuple#merge(other : NamedTuple)

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.

* Fix formatting in spec/std/named_tuple_spec.cr
  • Loading branch information
Papierkorb authored and RX14 committed Sep 25, 2017
1 parent 13db75b commit ecd3368
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
6 changes: 6 additions & 0 deletions spec/std/named_tuple_spec.cr
Expand Up @@ -297,6 +297,12 @@ describe "NamedTuple" do
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, "im \"string": "works"}
b = {two: "Two", three: true, "new one": "ok"}
c = a.merge(b).merge(four: "Four").should eq({one: 1, two: "Two", three: true, four: "Four", five: 5, "new one": "ok", "im \"string": "works"})
end

it "does types" do
tuple = {a: 1, b: 'a', c: "hello"}
tuple.class.types.to_s.should eq("{a: Int32, b: Char, c: String}")
Expand Down
25 changes: 25 additions & 0 deletions src/named_tuple.cr
Expand Up @@ -159,6 +159,31 @@ 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.stringify}}: self[{{k.symbolize}}],{% end %} {% end %}
{% for k in U %} {{k.stringify}}: other[{{k.symbolize}}], {% end %}
}
{% end %}
end

# Returns a hash value based on this name tuple's size, keys and values.
#
# See also: `Object#hash`.
# See `Object#hash(hasher)`
def hash(hasher)
{% for key in T.keys.sort %}
Expand Down

0 comments on commit ecd3368

Please sign in to comment.