treble37
When "stringifying" keys in a map, would you want to convert struct keys to strings?
Just looking for a little feedback on a tiny helper library I built -
Sometimes I find the need to convert maps with atom keys to maps with string keys, so %{:foo => 2} becomes %{"foo" => 2}…Has anyone ever come across the need to “string-ify” date/datetime/naivedatetime/structs when they are map keys? (I actually have yet to see a usecase where a date/struct is a map key, so I’m curious what others’ needs are as I’m making a little package with some helpers)…
If so, what would your ideal “stringification” of a struct/datetime/date/naivedatetime look like?
For example a %User{} struct could be stringified to:
"%User{age: 27, name: \"john\"}"
Most Liked
michalmuskala
You could always consider using the String.Chars protocol with the Kernel.to_string/1 function and let the implementor of the data type decide if it has a sensible “stringly” representation.
kylethebaker
An issue I can see with the way you’ve shown is that %User{age: 27, name: "john"} and %User{name: "john", age: 27,} represent the same struct, but "%User{age: 27, name: \"john\"}" and "%User{name: \"john\", age: 27}" are different strings. In other words, when in string format the key order becomes relevant. This could be an issue if you’re trying to do lookups using the stringified key. You might be able to avoid it by sorting the keys in the map/struct when you convert it, so that you know age always appears before name in the string.
With structs you should only have atom keys, but there is also a situation where you have a regular map as a key. In this case you would probably approach it the same way as structs, but you would need to consider that this map can itself have maps as keys (which may have maps as keys (which may have maps as keys (which may have…)). So you will need to approach it recursively and could end up with things like: %{%{%{%{\"foo\" => \"bar\"} => \"bax\"} => \"baz\"} => \"biz\"}.
When stringifying the map keys you lose the ability to reliably reverse the map to its original state (was %{"foo" => 1, "bar" => 2} originally %{foo: 1, bar: 2} or %{foo: 1, "bar" => 2}?). This also means that there are several different maps that could stringify into the same value. A map that has all string keys could have originally been a map that contained all atom keys, or a map that contained all string keys and a single atom key, or half and half, etc. If you’re treating atoms and string keys as the same then this might not be an issue, but this leads to situations where two values will have the same string key but would fail an equality check: stringify(foo) == stringify(bar) but bar != foo.







